下面的代码都能正常编译通过(编译环境为VS2010)
一、
一个奇怪的现象:
1. 代码如下:
int *a;
cout << &a << endl;
cout << a << endl;
没有报错;
2. 代码改成:
int *a;
cout << a << endl;
cout << &a << endl;
会报错。
代码2的第二行会报错“Run-Time Check Failure #3 - The variable 'a' is being used without being initialized",本来对未被初始化的指针进行操作报错很好理解。但是代码1却不报错了,第三行会输出调试窗口中a的值(无论代码1还是代码2当程序调试完int* a时,在调试窗口都会显式a的值为0xcccccccc,且无论运行多少次结果都相同,0xcccccccc似乎是编译器在编译阶段给未初始化指针分配的固定值)。
二、
定义一个数组:
int a[10]; //不对它进行初始化的情况下,必须在中括号内指定数组大小,而不能为空。不能写成int [];
此时编译器会自动为数组名a分配值,可以对数组a的元素进行赋值,在访问未赋值的元素时会出问题(类似于问题二)。
1. 代码如下
int c[1];
c[0] = 1;
cout << c << endl;
cout << c[0] << endl;
cout << c[1] << endl;
2. 代码改成
int c[1];
c[0] = 1;
//cout << c << endl; //注释掉第三行
cout << c[0] << endl;
cout << c[1] << endl;
当代码2运行到第5行时报错,问题与一中相同,都是未初始化的错误;代码二能正常运行。
从以上分析,指针的地址似乎和数组名起着相同作用,先对其进行标准输出操作,再运行剩下代码,都不会出问题,反之则不行。
不同之处是,编译器给未初始化的指针分配固定值,而每次给数组名分配不同的值;未初始化的指针变量不能直接像数组名那样使用中括号索引操作元素。
三、
要访问数组未赋值的索引除了使用二中代码1外还可以使用如下代码:
int k[20];
int* pk = k;
cout << pk[11] << endl;
上述代码输出-858993460(cccccccc的十进制形式),且在数组定义范围内pk[i]的输出皆为此值。
三、
char* 类型的特殊之处:
1.
可以直接对char* 类型的指针变量初始化(但不能用列表初始化)
且可以用char*类型的指针变量访问字符串元素。
2.
char* a = "12345678";
cout << a << endl;
直接输出字符串,而整型指针则只能输出指针变量对应的值,要访问字符指针变量的值可以使用cout << (void *)a << endl;。
四、小结
VS2010自动给未初始化的整型(包括char和指针)赋值0Xcccccccc,给float赋值-1.0737418e+008,给double赋值-9.2559631349317831e+061。
编译器自动用0填充未初始化的静态变量和全局变量,字符类型用‘ ’填充。在编译阶段编译器会自动给未初始化的变量分配地址。