Chinaunix首页 | 论坛 | 博客
  • 博客访问: 710483
  • 博文数量: 214
  • 博客积分: 5015
  • 博客等级: 大校
  • 技术积分: 2285
  • 用 户 组: 普通用户
  • 注册时间: 2006-06-18 17:02
文章分类

全部博文(214)

文章存档

2008年(43)

2007年(171)

我的朋友

分类:

2007-11-18 18:19:46

我们知道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 。
---------------------------

补充:程序中变量只能被定义一次,(所谓定义,就是为其分配空间),
所以在全局中遇到:
int a;
编译器不会立即认为其是定义,已防止后面遇到int a=1(如果遇到int a=1,这样必定是定义的语句,就会立即分配空间);而int a;(这种不能确定是定义还是声明的),如我前面所说,必须在后来找符号表时才能确定。


阅读(2264) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~