各种标识符的作用域是不相同的,有的是程序级,有的是文件级,还有函数级和程序段级。下面列举出一些标识符的不同作用域级别。 函数有程序级的,如外部函数;有文件级的,如内部函数。 变量中,外部变l孜属于程序级,外部静态变墩属于文件级,函数形参属于函数级。还有定义或说明在函数内的自动变量和内部静态变量以及寄存器变晕都属于函数级的,定义在分程序内的自动的、内部静态的和寄存器的变量属于程序段级的语句标号属于函数级的。 语句标号属于函数级的。 符号常量属于文件级的。
这里所说的程序级的是指作用范围(即作用域)在整个程序内,包含该程序的所用文件。同样级的是指作用范围在定义它的文件中,往往是从定义时开始。函数级的是指作用范围在定义它的函数体内;程序段级的是指作用域在定义它的分程序内。
5.4.2 重新定义变量作用域规定
C语言中,一般说来变量不能重复定义,这是指在相同的作用域内,不能有同名变量存在。
但是。在不同的作用域内,允许对某个变量进行重新定义。例如,在某个函数体内定义了一个int型变量a,这时不可以在同一个函数体内再定义一个float型变量ao但是,可以在该函数体内的某个分
程序中,对变量a重新定义,于是在整个函数体内的不同分程序中将出现同名变量。这时,它们的作用域又是如何规定的呢?关于重新定义的变量的作用域规定如下。
在函数体或分程序内可以各自定义变量,在函数体内又允许嵌套分程序。在函数体或外层分程序中定义的变量。如果在内层分程序中没有重新定义,则在内层分程序中将仍s}右效;如果在内层分程序巾进行了重新定义,则外层中的该变敏被隐藏起来,而在内层中起作用的是内层重新定义的变量,当退出内层程序又回到外层分程序或函数体内时,外层定_义的该变量又恢复出来,仍然起作用。 下面通过一个程序例子来理解和体会上述规定的含义, [例5.11〕分析下列程序的输出结果。 main ( ) {
int a=2,b=4,c=6
printf(\); { int b=8: float c=8. 8;
printf(\); a=b;
{ Int c; c=b:
printf(\); }
printf(\); }
printf(\) 执行该程序输出结果如下: 2,4,6 2,8,8. 8 8,8,8 8,8,8. 8 8,4.6
说明:该程序仅有'个主函数main( ),该函数中定义了a, b,.三个int型变量,并斌了初值。函数体内包含了一个分程序。该分程序内,重新定义了变量b和c,并赋了初值,这时函数体内定义的b和。在这里被隐藏起来,而重新定义的b和c在起作用,这时输出的a值是原来的,b和c是重新定义的。该分程序内,对a重新赋值,这不是重新定义,只是改变了a的值,因为a在这里是可见的。然后,在该分程序中,又定义了一个分程序,称内层分程序。在内层分程序
中,重新定义了。,并给它赋了值,在这里,开始定义的a仍然可见,开始定义的b仍被隐藏,外层分程序中重新定义的b是可见的,这里定义的c在起作用,外层分程序定义的。也被隐藏起来。当退出内层分程序后,开始定义的a和外层分程序定义的b和。是可见的。这时在内层分程序中,被隐藏的b和c被恢复了。当退出外层分程序后,开始定义的a和b,c都可见的。而被重新定义的b和c不可见了。值得注意的是变量a在整个函数体的任何部分都是可见的,因此,不论在何处它的值被改变后,则仍然保留其改变后的值。
5.5.1 变量的存储
C语言规定变量的存储类分为如下4种: (1)自动存储类变量(auto); (2)寄存器存储类变量(register); (3)外部类变量(extern); (4)静态类变量(static).
下面从两个方面来讨论不同存储类的特征,一是作用域和寿命,二是初始化。
1.不同存储类变蚤的作用域和寿命
(1)自动类变量的作用域是在定义它的函数体或分程序内,一旦退出了该函数体或分程序,则是不可见的。这类变量的寿命是短的,
它被存放在内存的动态存储区内。每次进人定义它的分程序或函数体内被动态分配存储区域,一旦退出该分程序或函数体后,所占用的内存区域被释放掉,即不存在了。
自动类变量一定出现在函数体或分程序内,自动类变量的存储类说明符是auto.多数情况下该说明符被省略。前面讲过的程序中凡在函数体或分程序内出现的没有加存储类说明符的都是自动类的。 总之,自动类的特点是作用域小、寿命短,可见性和存在性是一致的口即可见时即存在,一旦不可见了,也就不存在了。
(2)寄存器类变量的作用域和寿命与自动类变量相同,即作用域是在定义它的函数体或分程序内,寿命是短的。这类变量与自动类变量的区别在于寄存器类变量有可能被存放在GPU的通用寄存器中。如果这类变量数据被存放到通用寄存器中,则将大大提高对数据的存取速度。到底所定义的寄存器类变量能否被存放到通用寄存器中,这取决于当时CPU是否有空闲的通用寄存器。如果没有被存放到通用寄存器中,则按自动类变量处理。在一个程序中,定义寄存器类变量时,应注意如下几点:
①定义的寄存器变量的个数不能太多,因为空闲的通用寄存器数目是很有限的。
②由于通用寄存器的数据长度的限制,一般定义为寄存器变量的数据类型为char型或int型。数据长度太大的数据通用寄存器放不