初始化
自动变量和静态变量的初始化存在一个重要区别。在静态变量的初始化中,我们可以把执行程序文件想要初始化的值放在当程序执行时将会使用的
位置。
static关键字
当它用于函数定义时,或用于代码块之外的变量声明时,static关键字用于修改标识符的链接属性,从external改为internal,但标识符的存储类型
和作用域不受影响。用这种方式声明的函数或变量只能在声明它们的源文件中访问。
当它用于代码块内部的变量声明时,static关键字用于修改变量的存储类型,从自动变量修改为静态变量,但变量的链接属性和作用域不受影响。
用这种方式声明的变量在程序运行之前创建,并且在程序整个执行期间一直存在,而不受每次在代码块开始执行时创建,在代码块执行完毕后销毁。
作用域和存储类型示例
属于文件作用域的声明在缺省情况下为external链接属性,所有第一行的a的链接属性为external。如果b的定义在其他地方,第二行的extern关键字
在技术上并非必须,但在风格上加上这个关键字为好。第三行的static关键字修改了c的缺省链接属性,把它改为internal。声明了变量a和b(具有external
链接属性)的其他源文件在使用这两个变量时,所访问的是声明于此处的这两个变量。但是,变量c只能由这个源文件访问,因为它具有internal链接属性。
int a = 5;
extern int b;
static int c;
int d(int e)
{
int f = 15;
register int b;
static int g;
extern int a;
...
{
int e;
int a;
extern int h;
...
}
...
{
int x;
int e;
...
}
...
}
static int i()
{
...
}
...
变量a、b、c的存储类型为静态,表示它们并不是存储于堆栈中。因此,这些变量在程序执行之前创建,并一直保持它们的值,知道程序结束。
当程序开始执行时,变量a将初始化为5。
这些变量的作用域一直延伸到这个源文件结束为止,但是第7行和第13行声明的局部变量a和b在那部分程序中讲隐藏同名的静态变量。
第4行声明了2个标识符。d的作用域从第4行直到文件结束。函数d的定义对于这个源文件中任何以后想要调用它的函数而言起到了函数原型
的作用。作为函数名,d在缺省情况下具有external链接属性,所有其他源文件只要在文件上存在d的原型,就可以调用d。如果我们将函数
声明为static就可以把它的链接属性从external改为internal,但这样做将使其他源文件不能访问这个函数。对于函数而言,存储类型并不是
问题,因为代码总是存储于静态内存中。
参数e不具有链接属性,所有我们只能从函数内部通过名字访问它。它具有自动存储类型,所以它在函数被调用时被创建,当函数返回时候消失。
6 至8 行声明局部变量,所有它们的作用域到函数结束为止。它们不具有链接属性,所有它们不能在函数的外部通过名字访问(这是它们被成为局部
变量的原因)。f的存储类型是自动,当函数每次被调用时,它通过隐式赋值被初始化为15。b的存储类型是寄存器类型,所有它的初始值的垃圾。
g的存储类型是静态,所有它在程序的整个执行过程中一直存在。当程序开始执行时,它被初始化为20。当函数每次被调用时,它并不会被重新初始化。
第9行的声明不需要,这个代码块位于第1行声明的作用域之内。
第12和13 行为代码块声明局部变量。它们都具有自动存储类型,不具有链接属性,它们的作用域延伸至16行。
第14行使全局变量h在这个代码块内可以被访问。它具有external链接属性,存储于静态内存中,这是唯一一个必须使用extern关键字的声明,如果
没有它,h将变成另一个局部变量。
阅读(1356) | 评论(0) | 转发(0) |