存储期
在函数中声明的变量,并不是从程序开始到程序结束始终有效的。变量的生存期也就是生命有两种,它们可以通过存储期(storage duration)这个概念来体现。
自动存储期
在函数中不使用存储类说明符static
而定义出的对象(变量),被赋予了自动存储期(automatic storage duration), 它具有以下特性。
程序执行到对象声明的时候就创建出了相应的对象。而执行到包含该声明的程序块的结尾,也就是大括号
}
的时候,该对象就会消失。
也就是说,该对象拥有短暂的寿命,另外,如果不显式地进行初始化,则该对象会被初始化为不确定的值。
被赋予自动存储期的对象,在程序执行到int ax = 0;
的时候,就被创建出来并且进行初始化。
静态存储期
在函数中使用static
定义出来的对象,或者在函数外声明定义出来的对象被赋予了静态存储期(static storage duration),它具有以下特性。
在程序开始执行的时候,具体地说是在
main
函数执行之前的准备阶段被创建出来,在程序结束的时候消失。
也就是说,改对象拥有"永久"的寿命。另外,如果不显式地进行初始化,则该对象会自动初始化为0。
被赋予了静态存储期的对象,会在main
函数开始执行之前被初始化。因此,虽说程序执行的时候会经过static int sx = 0;
的声明,但其实那个时候并没有进行初始化处理,也就是说该声明并未执行赋值处理。
#include <stdio.h>
int fx = 0; //静态存储期,文件作用域
void func(void)
{
static int sx = 0; //静态存储期+块作用域
int ax = 0; //自动存储期+块作用域
printf("%3d%3d%3d\n",ax++, sx++, fx++);
}
int main(void)
{
puts("ax sx fx");
puts("-------------");
for (int i = 0; i < 10; i++) {
func();
}
puts("--------------");
return 0;
}
auto
和register
在函数通过存储类说明符auto
和register
声明定义出的变量,也被赋予了自动存储期。通过auto int ax = 0;
进行的声明和不使用auto
进行的声明在编译的时候是完全相同的。因此auto
就显得有些多余了。
另外,使用register
进行的声明register int ax = 0;
,在源程序编译的时候,变量ax
不是保存在内存中,而是保存在更高速的寄存器中,然而,由于寄存器的数量有限,所以也不是绝对的。
现在编译技术已经十分先进了,那个变量保存在寄存器中更好都是通过编译自行判断并进行最优化处理的(不仅如此,保存在寄存器中的变量在程序执行的时候也可能发生改变)。
使用register
进行声明也渐渐变得没有意义了。