cout 字符指针和int等指针的解释

问题来源

在牛客网的讨论群里,有人提出了这样的问题代码:

char *p  = NULL;
cout << p;
******
int *q = NULL;
cout << q;

上述代码在windows下面使用vs,一个会报错一个不会报错~ 但是在linux下面并不会报错~

猜想

  • 字符指针是直接打印指针指向的值(字符串),访问了空指针的内容;
  • int指针,输出是打印指针的值(null=0),所以不会报错.
  • 而linux下面不会报错,那肯定是不同编译器的处理不一样了~

验证

  • 程序在ubuntu14.04上跑的,使用g++
  • 并没有去windows下面验证,但看过别人运行类似程序的结果

    程序如下:

#include<iostream>
#include<cstring>
using namespace std;
int main()
{
    char a[] = "hello,world!";
    cout << "a‘s address is " << &a << endl;
    char *p = a;
    cout <<"the p‘s value is: " << (void *)(p) << endl;
    cout << "the content is: " << p << endl;

    p = NULL;
    cout <<"the p‘s value is: " << (void *)(p) << endl;
    cout << "the content is: " << p << endl;
    if(cout.bad()) {
        cout.clear();
        cout << endl;
        cout << "  If @p __sb is NULL, the stream will set failbit in its error state." << endl;
    }

    int *q = NULL;
    cout <<"q‘s value is " << q << endl;
    cout << "the content is " << *q << endl;
    return 0;
}

编译运行:

[email protected]:~/code/C/pointer$ ./a.out
a‘s address is 0xbf897d7f
the p‘s value is: 0xbf897d7f
the content is: hello,world!
the p‘s value is: 0
the content is:
  If @p __sb is NULL, the stream will set failbit in its error state.
q‘s value is 0
段错误 (核心已转储)

结论

  • 如猜测的一样, cout 的<< 在重载时,遇到char * 和int *的输出解释是不一样的
  • g++在遇到空字符指针时,会在错误状态中,置为fallbit,这个通过查看源码是可以找到的:

/**

  • @brief Extracting from another streambuf.
  • @param __sb A pointer to a streambuf

    *

  • This function behaves like one of the basic arithmetic extractors,
  • in that it also constructs a sentry object and has the same error
  • handling behavior.

    *

    * If @p __sb is NULL, the stream will set failbit in its error state.

    *

  • Characters are extracted from @p __sb and inserted into @c *this
  • until one of the following occurs:

    *

    • the input stream reaches end-of-file,
    • insertion into the output sequence fails (in this case, the
  • character that would have been inserted is not extracted), or
    • an exception occurs while getting a character from @p __sb, which
  • sets failbit in the error state

    *

  • If the function inserts no characters, failbit is set.

    */

    __ostream_type&

    operator<<(__streambuf_type* __sb);

时间: 2024-10-15 03:21:30

cout 字符指针和int等指针的解释的相关文章

C语言:int型指针与char型指针本质

---恢复内容开始--- 我的理解是,不管定义时将指针定义成何种类型,指针本质上都是一个数字,其位数由编译器来决定. 比如我的编译器是32位,那么无论是定义一个char *pc还是定义一个int *pi,本质上pc与pi都是一个32位的数,但是由于"char *" 和 "int *"的限制,所以pc++是自加8bit,而pi++是自加16bit. 1 // int指针与char指针.cpp : 2 // 看看“char型指针”与“int型指针”本质上有什么区别 3

你必须知道的指针基础-7.void指针与函数指针

一.不能动的“地址”—void指针 1.1 void指针初探 void *表示一个“不知道类型”的指针,也就不知道从这个指针地址开始多少字节为一个数据.和用int表示指针异曲同工,只是更明确是“指针”. 因此void*只能表示一个地址,不能用来&取值,也不能++--移动指针,因此不知道多少字节是一个数据单位. int nums[] = {3,5,6,7,9}; void* ptr1 = nums; //int i = *ptr1; // 对于void指针没法直接取值 int* ptr2 = (i

int main (int argc, const char * argv[0]) 中参数的含义;指针数组和数组指针

恩,有的编译器初始化时候会产生这样的参数 argc是命令行总的参数个数,argv[]是argc个参数,其中第0个参数是程序的全名 1. 几种C++ 常见的参数种类 int main(void); int main(); int main(int argc, char **argv);   //等价于int main(int argc, char *argv[]),是否等价呢?是不是前一个可以表示任意长度的任意个数组,后一个只是定长的任意个数的数组?见下面 int main(int argc, c

指针数组,数组指针,指针函数,函数指针,二级指针详解

先看个简单的:char *p,这定义了一个指针,指针指向的数据类型是字符型,char  *(p)定义了一个指针P: char *p[4], 为指针数组,由于[]的优先级高于*,所以p先和[]结合,p[]是一个数组,暂时把p[]看成是q,也就是char *(q),定义了一个指针q,只不过q是一个数组罢了,故定义了一个数组,数组里面的数据是char *的,所以数组里面的数据为指针类型.所以char *p[4]是四个指针,这四个指针组成了一个数组,称为指针数组,既有多个指针组成的数组. char(*p

C++——指针---指向数组的指针---指向字符串的指针--指向函数的指针--指针的指针--指针的引用

一.指向数组的指针 代码示例1: 1 int main() 2 { 3 int a[10]={0,2,4,6,8,10,12,14,16,18}; 4 int *p; 5 for(p=&a[0];p<&a[0]+10;p++) 6 printf("%d ",*p); 7 } 代码示例2: int a[10]={0,2,4,6,8,10,12,14,16,18}; int *p; p=a; printf("%d\n",*(a+5));//注意加括

c指针 --笔记2返回指针值的函数

返回指针值的函数 一般带回指针值的函数,定义形式为: int *a (int x, int y); 看这个经典案例: #include <stdio.h> int main(int argc, char const *argv[]) { double score[][4] = {{60.0, 70.0, 80.5, 20.1}, {60.0, 70.0, 80.5, 21.1}, {60.0, 70.0, 80.5, 22.1}}; double *search(double(*pointer

C/C++笔试篇-------二维指针数组、数组指针的用法

1.废话不多说,先上代码: #include <iostream> using namespace std; int main(void) { int v[2][5] = {{1,2,3,4,5},{6,7,8,9,10}}; int (*a)[5] = v; //指针数组,指针指向数组 a[5],a[5]里面是int数值 该指针等于v的地址 cout<<(*a+1)<<endl; //*a是v[0][0]的地址. 0x22fe04 cout<<(*a+2)

【转】 指针函数与函数指针的区别

一. 在学习arm过程中发现这“指针函数”与“函数指针”容易搞错,所以今天,我自己想一次把它搞清楚,找了一些资料,首先它们之间的定义: 1.指针函数是指带指针的函数,即本质是一个函数.函数返回类型是某一类型的指针 类型标识符    *函数名(参数表) int *f(x,y); 首先它是一个函数,只不过这个函数的返回值是一个地址值.函数返回值必须用同类型的指针变量来接受,也就是说,指针函数一定有函数返回值,而且,在主调函数中,函数返回值必须赋给同类型的指针变量. 表示: float *fun();

指针数组和数组指针

指针数组:首先它是一个数组,数组的元素都是指针.它是“储存指针的数组”的简称.int *p1[10];数组指针:首先它是一个指针,它指向一个数组.它是“指向数组的指针”的简称.   int (*p2)[10]; 这里需要明白一个符号之间的优先级问题,关键在于p1.p2先和谁结合.“[]”的优先级比“*”要高.p1 先与“[]”结合,构成一个数组的定义,数组名为 p1,int *修饰的是数组的内容,即数组的每个元素.那现在我们清楚,这是一个数组,其包含 10 个指向 int 类型数据的指针,即指针