C Primer Plus 第12章 12.2 存储类说明符
博客专区 > idreamo 的博客 > 博客详情
C Primer Plus 第12章 12.2 存储类说明符
idreamo 发表于1年前
C Primer Plus 第12章 12.2 存储类说明符
  • 发表于 1年前
  • 阅读 17
  • 收藏 0
  • 点赞 0
  • 评论 0

新睿云服务器60天免费使用,快来体验!>>>   

摘要: C语言中有5个关于存储类说明符的关键字。

C语言中有5个关于存储类说明符的关键字,它们是auto、register、static、extern以及typedef。关键字typedef与内存存储无关,由于语法原因被归入此类。特别地,不可以在一个声明中使用一个以上存储类说明符,这意味着不能将其他任一存储类说明符作为typedef的一部分。

说明符auto表明一个变量具有自动存储时期。该说明符只能用在具有代码块作用域的变量声明中,而这样的变量已经拥有自动存储时期,因此它主要用来明确指出意图,使程序更易读。

说明符register也只能用于具有代码块作用域的变量。它将一个变量归入寄存器存储类,这相当于请求将该 变量存储在一个寄存器内,以更快地存取。它的使用也使您不能获得变量的地址。

说明符static在用于具有代码块作用域的变量的声明时,使该变量具有静态存储时期,从而得以在程序运行期间(即使在包含该变量的代码块并没有运行时)存在并保留其值。变量仍具有代码块作用域和空链接。static在用于具有文件作用域的变量的声明时,表明该变量具有内部链接。

说明符extern表明您在声明一个已经在别处定义了的变量。如果包含extern的声明具有文件作用域,所指向的变量必然具有外部链接。如果包含extern的声明具有代码块作用域,所指向的变量可能具有外部链接也可能具有内部链接,这取决于该变量的定义声明。

下面给出了一个使用全部5种存储类的小程序。它由两个文件组成,因此您需要多文件编译。程序的主要目的是使用全部5种存储类,并非提供一个设计范例;更好的设计将不需要文件作用域变量。

程序清单12.5  parta.c文件

//parta.c  --各种存储类
#include <stdio.h>
void report_count();
void accumulate(int k);
int count = 0;    //文件作用域,外部链接
int main(void)
{
    int value;    //自动变量
    register int i;    //寄存器变量

    printf("Enter a positive integer(0 to quit): ");
    while(scanf("%d",&value) == 1 && value > 0)
    {
        ++count;    //使用文件作用域变量
        for (i=value;i>=0;i--)
            accumulate(i);
        printf("Enter a positive integer(0 to quit): ");
    }
    report_count();
    return 0;
}
void report_count()
{
    printf("Loop executed %d times\n",count);
}

程序清单12.6  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和partb.c的代码不必要地纠缠在了一起)。在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 

 

  • 打赏
  • 点赞
  • 收藏
  • 分享
共有 人打赏支持
粉丝 12
博文 139
码字总数 224743
×
idreamo
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: