1 #include <stdio.h> 2 3 float i = 3; 4 int j = *(int *)(&i) ; 5 6 int main (int argc , char *argv[]) 7 { 8 printf( "i = %f \n" , i ) ; 9 printf( "j = %#x \n" , j); 10 return 0; 11 }
对于高手,一眼就能看出其中的问题,不过对标准C语言不是很明白的可能就搞不清楚了。
编译,gcc -o text text.c、./text,出现如下错误:
1 text.c:4: error: initializer element is not constant
其中原因在于: C语言初始化一个全局变量或static变量时,只能用常量赋值,不能用变量赋值!上面的代码第3行的i是个变量,于是第4行出错。这里注意,即使第3行用const int a = 100,编译器也视a为变量。
------------------------------------------------------------------------------我是分割线------------------------------------------------------------------------------
在C++中对于以下语句:
// 全局域
int i = 3;
int j = i;
编译时将i 放入.data 段,设置其值为3.
而对于j ,编译器遇到这种语句,只知道j = i ,由于 i 是变量,不是常量,编译器无法在编译时直接得到它的值,编译器只会找到i 的地址, 然后读取这个地址的内容,再把这个内容写入 j 的地址。
计算机只会“取 i 的地址,把3 放到 i 的地址中,取 i 的地址,读取这个地址中的内容,取 j 的地址,把这个内容 写入j 的地址。编译器无法在编译时求得一个非常量的值,它只能在运行时通过读取变量地址来间接得到变量的值,而全局变量在编译时就必须确定其值,故C有静态存储区数据必须用常量初始化的规定。
在编译时只能用常量去初始化一个静态存储区的数据,而不能用“读取某个变量的内容”来初始化,所以编译器会将j 放入 .bss段,默认值为0 ,然后添加一条语句在运行时读取i 的值,再赋给j。这条语句在调用main()之前完成。