C Primer Plus学习 三十八 存储类说明符

        您可能己经注意到关键字static和extern的意义随上下文而不同。C语言中有5个作为存储类说明符的关键字,它们是auto、register、static、extern以及typedef。关键字typedef与内存存储无关,由于语法 原因被归入此类。特别地,不可以在一个声明中使用一个以上存储类说明符,这意味着不能将其他任一存 储类说明符作为typedef的一部分。
        说明符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;

}

}

下面是一个运行示例:

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

        在该程序中,具有代码块作用域的静态变量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。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值