全部博文(346)
分类: C/C++
2008-09-02 13:17:53
全局变量&局部变量
当全局变量和局部变量同名时,会遮蔽全局变量,在函数内引用此变量时会用到同名的局部变量,而不会用到全局变量(如果想引用全局变量需要加上::)。而且局部变量可以相互遮蔽,如if嵌套,for嵌套等。
这都与局部变量的作用域有关,而作用域又根据各编译器的实现有关,这就联系到编译原理的内容(顺便复习一下)。
一般而言,标示符的符号表要包含几种属性:名字、类型、存储类别、作用域、可视性、存储分配信息。
1)名字:
符号表中符号名一般不允许重名,若程序出现重名标示符,则根据语言的定义, 按照该标示符的作用域和可视性规则进行相应的处理。
若程序允许重载,函数名通过它们的参数个数、类型、返回值来区分。
2)类型:
决定变量的数据在存储空间的存储格式,还决定了在变量上可施加的运算。
3)存储类别:
其定义方法有两种形式:关键字指定,变量定义+位置。
这个属性是编译过程语义处理,检查和存储分配的重要依据,还决定了它的作用 域可视性生命周期等问题。
4)作用域和可视性:
通常一个变量的作用域就是该变量可以出现的地方;函数形参作为函数内部变量处理;分程序结构本身含有局部变量声明的语句。
5)存储分配:
编译程序一般根据标示符的存储类别以及他们出现的位置和次序来确定每个变量应分配的存储区及该区域的具体位置。
静态存储区 公共静态区 公共+外部 整个域作用
局部静态区 局部静态 局部
动态存储区
标示符在源程序中出现的位置和先后顺序决定了标示符在存储区中的具体位置,即一个偏移量。
关于符号表的建立:
如程序:
main()
{int a = 1; float c =0.1;
{
float a =1.0;
{float x=5.5,b =7.1;}
{int b =9; c =a+b+c;}
}
}
1.建立符号表第一层到内存中main的指向;
2.建立符号表第二层到内存中a,c的指向,指向a;
3.建立符号表第三层到内存中a的指向,指向a;(第二层的a与第三层的a不同)
4.建立符号表第四层到内存中x,b的指向,遇到后一个括号}表明本层结束,建立内存中结束项,
然后从结束项建立 指针,指向上层最后一个元素,即第三层的a,然后删除本层的符号表到内
存中的指针;
......
n.最后形成的结果是符号表到内存中共有三个指向,分别指向main、a和c的a、a,然后又很多
结束项指回前三层。
(由于不会在blog里用图形,所以不能更形象地标示出来。等以后整明白的。)
特别一点:
如果是不同的C文件中,以static方式来声明同名的全局变量,如果要正常运行,要求只能有一个C文件对此变量赋值,此时连接不会出错
补充:
Static全局变量和普通全局变量的区别