文档章节

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

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Spring Cloud Gateway真的有那么差吗?

前言 Spring Cloud从一开始最受大家质疑的就是网关性能,那是由于Spring Cloud最初选择了使用Netflix几年前开源的Zuul作为基础,而高性能版的Zuul 2在经过了多次跳票之后,对于Spring这样的整...

Java小铺
40分钟前
1
0
SpringBoot远程调试,远程debug你的线上项目

开发环境中代码出错了,可以利用IDE的debug功能来进行调试。那线上环境出错呢? 一、假设我们的项目是部署在tomcat中,那我们就需要对tomcat进行一定对配置,配置如下。 1. windows系统中,找...

nonnetta
45分钟前
0
0
JAVA秒杀优化方向

秒杀优化方向 将请求尽量拦截在系统上游:传统秒杀系统之所以挂,请求都压倒了后端数据层,数据读写锁冲突严重,几乎所有请求都超时,流量虽大,下单成功的有效流量甚小,我们可以通过限流、...

小贱是个程序员
52分钟前
0
0
C# 统计字符串中大写字母和小写字母的个数

static void Main() { int count1 = 0; int count2 = 0; Console.WriteLine("请输入字符串"); string str = Convert.ToString(Consol......

熊二的爸爸是谁
55分钟前
0
0
分布式服务框架之远程通讯技术及原理分析

在分布式服务框架中,一个最基础的问题就是远程服务是怎么通讯的,在Java领域中有很多可实现远程通讯的技术,例如:RMI、MINA、ESB、Burlap、Hessian、SOAP、EJB和JMS等,这些名词之间到底是...

老道士
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部