文档章节

C Primer Plus 第12章 12.2 存储类说明符

idreamo
 idreamo
发布于 2016/11/19 07:30
字数 1073
阅读 18
收藏 0

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 

 

© 著作权归作者所有

共有 人打赏支持
idreamo
粉丝 14
博文 139
码字总数 224743
作品 0
青岛
产品经理
C Primer Plus 第12章 12.9 总结

用于存储程序数据的内存可用存储时期、作用域和链接来表征。存储时期可以是静态的、自动的或者分配的。如果是静态的,内存在程序开始执行时被分配,并在程序运行时一直存在。如果是自动的,变...

idreamo
2016/12/28
25
0
C Primer Plus 第12章 存储类、链接和内存管理

12.1 存储类 C为变量提供了5种不同的存储模型,或称为存储类。还有基于指针的第6种存储模型,本章稍后(“分配内存malloc()和free()”小节)将会提到。可以按照一个变量(更一般地,一个数据...

idreamo
2016/11/01
18
0
C Primer Plus 第3章 数据和C

3.1示例程序 程序清单3.1 rhodium.c程序 ------ 3.2 变量与常量数据 有些数据可以在程序使用之前预先设定并在整个运行过程中没有变化,这称为常量; 另外的数据在程序运行过程中可能变化或被...

idreamo
2016/05/10
12
0
C Primer Plus 第8章 字符输入/输出和输入确认 8.6 输入确认

程序清单8.7 使用两个函数来向一个算术函数传送整数,该函数计算特定范围内所有整数的平方和。程序限制这个特定范围的上界不应该超过1000,下界不应该小于-1000。 8.6.1 分析程序 首先集中讨...

idreamo
2016/06/30
31
0
C Primer Plus 第5章 运算符、表达式和语句 5.5 类型转换

1、当出现在表达式里时,有符号和无符号的char和short类型都将被自动转换为int,在需要的情况下,将自动被转换为unsigned int。在K&RC下,但不是在当前的C下,folat将被自动转换为double.因为...

idreamo
2016/05/21
33
0

没有更多内容

加载失败,请刷新页面

加载更多

LINUX中如何查看某个端口是否被占用(转发)

LINUX中如何查看某个端口是否被占用 之前查询端口是否被占用一直搞不明白,问了好多人,终于搞懂了,现在总结下: 1.netstat -anp |grep 端口号 如下,我以3306为例,netstat -anp |grep 33...

覃大光
30分钟前
0
0
JBolt 1.5.0新版发布,升级到支持最新版JFinal和Jetty,实现了在线更新插件功能

JBolt是一个JFinal极速开发框架 定制版IDE插件 目前仅有Eclipse插件版,Idea插件版正在开发中。 JBolt的详细使用教程请移步到这里 =====版本1.5.0 更新内容 2018年10月13日10:41:52===== 注意...

山东-小木
33分钟前
0
0
laravel 微信支付

1.composer加载laravel微信支付第三方文件 composer require "overtrue/laravel-wechat:~4.0" composer require simplesoftwareio/simple-qrcode 1.3.* //composer生成二维码文件 2.改confi......

vio小黑
45分钟前
1
0
学习设计模式——抽象工厂模式

1. 认识抽象工厂模式 1. 定义:提供一个创建一系列相关或互相依赖的对象的接口,而无需指定它们具体的类。 2. 组成结构: AbstractFactory:抽象工厂类,定义创建一系列对象的操作接口 Fact...

江左煤郎
46分钟前
2
0
ES6的let块级作用域和变量不可提升导致一个比较容易出现的错误

今天在写NodeJS代码的时候出现一个变量一直提示未定义,简化后的代码如下: let param = 1;{ console.log(param);} 就在想,不至于啊。不是继承上层的声明吗? 继续看下去,发现原来...

MKjy
52分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部