2 局部变量及其作用域和生存期
2.1 auto变量
当在函数内部或复合语句内定义变量时,如果没有指定存储类,或使用auto说明符,系统默认所定义的变量为自动类别。因此:
float a; 等价于 auto float a;
auto变量的存储单元被分配在内存的动态存储区。当进入函数体时,系统自动为auto变量分配存储单元;退出时自动释放这些存储单元。这类局部变量的作用域是从定义的位置起,到函数体结束为止。由于函数的频繁调用,动态存储区内为某个变量分配的存储单元位置随程序的运行而改变,变量的初值也随之而变,所以未赋初值的自动变量其值是不确定的。
若通过定义语句给自动变量赋初值,赋初值的操作是在程序运行过程中进行的,每进入一次函数体,就赋一次指定的初值。使用这类局部变量的最突出优点是:可在各个函数间造成信息隔离,不同函数中使用同名变量也不会相互干扰,从而可避免因不慎赋值所导致的错误影响到其他函数。
2.2 register变量
寄存器变量也是自动类变量,它与auto变量的区别仅在于:用register说明的变量建议编译程序将变量的值保留在CPU的寄存器中,而不是像一般变量那样占内存单元。程序运行时,访问存于寄存器内的值要比访问存于内存中的值快得多。因此当程序对运行速度有较高要求时,把那些频繁引用的少数变量指定为register变量,有助于提高程序的运行速度。
说明:
(1)CPU中寄存器的数目是有限的,因此只能说明少量的寄存器变量。在一个函数中,允许说明为寄存器变量的数目不仅取决于CPU的类型,也与所用的C编译程序有关。当没有足够的寄存器来存放指定的变量,或编译程序认为指定的变量不适合放在寄存器中时,将自动按auto变量来处理。因此,register说明只是对编译程序的一种建议,而不是强制性的。
(2)由于register变量的值是放在寄存器内而不是放在内存中,所以register变量没有地址,也就不能对它进行求地址运算。
(3)register变量的说明应尽量靠近其使用的地方,以便提高寄存器的利用效率。这可以通过把对register变量的说明和使用放在复合语句中来实现。
2.3 静态存储类的局部变量
当在函数体(或复合语句)内部用static来说明一个变量时,可以称该变量为静态局部变量。静态局部变量的作用域仍与 auto、register 类的变量一样,但与后两者有两点本质上的区别:
(1)在整个程序运行期间,静态局部变量在内存的静态存储区中占据着永久性的存储单元。即使退出函数后,下次再进入函数时,静态局部变量仍使用原来的存储单元。由于并不释放这些存储单元,因此这些存储单元中的值得以保留,因而可以继续使用存储单元中原来的值。静态局部变量的生存期将一直延长到程序运行结束。
(2)静态局部变量的初值是在编译时赋予的,不是在程序执行期间赋予(自动变量是在程序执行过程中赋初值)。对未赋初值的静态局部变量,C编译程序自动给它赋初值0。
静态局部变量的上述特点,对于编写那些在函数调用之间必须保留局部变量值的函数是非常有用的。