说明符auto表明一个变量具有自动存储时期。该说明符只能用在具有代码块作用域的变量声明中,而 这样的变量已经拥有自动存储时期,因此它主要用来明确指出意图,使程序更易读。
说明符register也只能用于具有代码块作用域的变量。它将一个变量归入寄存器存储类,这相当于请求 将该变量存储在一个寄存器内,以更快地存取。它的使用也使您不能获得变量的地址。
说明符static在用于具有代码块作用域的变量的声明时,使该变量具有静态存储时期,从而得以在程 序运行期间(即使在包含该变量的代码块并没有运行时)存在并保留其值。变量仍具有代码块作用域和空 链接。static用于具有文件作用域的变量的声明时,表明该变量具有内部链接。
说明符extern表明您在声明一个己经在别处定义了的变量。如果包含extern的声明具有文件作用域, 所指向的变量必然具有外部链接。如果包含extern的声明具有代码块作用域,所指向的变量可能具有外部 链接也可能具有内部链接,这取决于该变量的定义声明。
总结:存储类
自动变量具有代码块作用域、空链接和自动存储时期。它们是局部的,为定义它们的代码 块(通常是一个函数)所私有。寄存器变量与自动变量具有相同的属性,但编译器可能使用速 度更快的内存或寄存器来存储它们。无法获取一个寄存器变量的地址。
具有静态存储时期的变量可能具有外部链接、内部链接或空链接。当变量在文件的所有函 数之外声明时,它是一个具有文件作用域的外部变量,具有外部链接和静态存储时期,.,如果在 这样的声明中再加上关键字static,将获得一个具有静态存储时期、文件作用域和内部链接的变 量„如果在一个函教内使用关键字static声明变量,变量将具有静态存储时期、代码块作用域 和空链接。当程序执行到包含变量声明的代码块时,给具有自动存储时期的变量分配内存,并在代码 块结束时释放这部分内存。如果没有初始化,这样的变量具有一个无效值。在程序编译时给具 有静态存槠时期的变量分配内存,并且在程序运行时一直保持。如果没有初始化,这样的变量 被设置为0。具有代码块作用域的变量局部于包含变量声明的代码块„
具有文件作用域的变量对文件中在它的声明之后的所有函數可见。如果一个文件作用域变 量具有外部链接,則它可被程序中的其他文件使用。如果一个文件作用域变量具有内部链接, 它只能在声明它的文件中使用。
下面给出了一个使用全部5种存储类的小程序。
parta.c文件
// parta.c ---各种存储类
#include<stdio.h>
void repotr_count();
void accumulate(int k);
int count=0; //文件作用域,外部链接
int main(void)
{
int value; //自动变置
register int i; //寄存器变童
printf("Enter a postitve integer(0 to quit)");
while(scanf("%d",&value)==1&&value>0)
{
++count; //使用文件作用域变置
for(i=value;i>=0;i--)
{
accumulate(i);
}
printf("Enter a postitve integer(0 to quit)");
}
repotr_count();
return 0;
}
void repotr_count()
{
printf("Loop executed %d times\n",count);
}
partb5.c文件
// partb.c --程序的其余部分
#include<stdio.h>
extern int count; //引用声明,外部链接
static int total=0; //静态定义,内部链接
void accumulate(int k); //原型
void accumulate(int k) // k具有代码块作用域、空链接
{
static int subtotal=0;
if(k<=0) //静态、空链接
{
printf("loop cycle %d\n",count);
printf("subtotal:%d;total:%d\n",subtotal,total);
subtotal=0;
}
else{
subtotal+=k;
total+=k;
}
}
下面是一个运行示例:
在该程序中,具有代码块作用域的静态变量subtotal保存运行时传递给函数accumulate ()的数值的部 分和具有文件作用域、内部链接的变量total保存运行时的总和。一旦有非正数传入,函数accumulate () 就报告total和subtotal的值;并在报告时将subtotal重置为0。parta.c中的函数accumulate ()函数原型是 必须的,因为文件包含了一个accumulate ()函数调用。对于partb.c来说,函数原型是可选的,因为这个 函数虽然定义了,但是并没有在该文件中被调用。函数同时使用外部变量count来记录main ()中的while 循环执行了多少次(顺便提一下,这是一个什么情形下不应使用外部变量的反面例子,因为它使parta.c和 partbx的代码不必要地纠缠在一起)》在parta.c中, main ()和 report_count ()共享 count。Enter a positive integer (0 to quit): 5
loop cycle: 1
subtotal: 15; total: 15
Enter a positive integer (0 to quit): 10
loop cycle: 2
subtotal: 55: total: 70
Enter a positive integer (0 to quit): 2
loop cycle: 3
subtotal: 3; total: 73
Enter a positive integer (0 to quit): 0
Loop executed 3 times