我们知道C语言中,局部变量分配顺序是固定的,可是你有没有想过全局变量分配的顺序呢?
没有,那么首先用2种方式运行下面的程序:
#include <iostream.h>
#define ONE 1 // 0
#if ONE
int a, b;
#else
int b, a;
#endif // ONE
void main()
{
#if ONE
cout << "TEST_ONE: 1st" << endl;
cout << &a << endl
<< &b << endl;
#else
cout << "TEST_ONE: 2nd" << endl;
cout << &b << endl
<< &a << endl;
#endif // ONE
}
// 结果是什么?
// 第1组是从低到高,第2组却是从高到低
// 好像全局静态存储区的分配还与变量名称有关(b就是比a地址高)
//------------------------------------------------------------------------------------------------------------------------------
为什么这样呢?
上面的程序中,变量确实是按字母顺序分配空间的。
但是如果在定义的时候把变量初始化:
#if ONE
int a=1 , b= 2;
#else
int b=1, a=2;
#endif // ONE
那么其地址顺序就是固定的,谁在前定义,它的地址就在前面。
综上我的结论是这样的:
这个和编译器在什么时候能够决定这是一个变量的定义有关。
在变量被初始化的时候,编译器在当前位置就能确定这是一个定义,所以立即为其分配空间。
而在变量未被初始化的时候,编译器在当前位置就不能确定这是一个声明还是定义,因为程序中可以写:
int a;
int a; //全局变量可以多次声明
int a;
那么在什么时候能确定这是定义呢?C中是在link的时候(C++中也许编译单个文件就能确定),不管是哪一种,他的前提都是已经扫描完了所有的代码,并把他们放入了符号表中,然后编译器开始从符号表中查看哪些变量是未定义的,如果没定义就补上定义,由于符号表是按字母顺序的,所以分配的变量也是按字母顺序的。
-------------------------------------
测试:
如果上面的推测正确的话,那么:
int a, b=2;
b的地址应该在a的前面。(因为b在当前位置被定义,而a在查看符号表时才能确定)
实验结果:a的地址远远大于b 。