首先介绍三个概念:

(1)作用域:作用域描述了程序中可以访问一个标识符的一个或多个区域。

一共有三种作用域:代码块作用域、函数原型作用域和文件作用域

a.代码块作用域:一个代码块是包含在开始花括号和对应结束花括号之间的一段代码,在代码块内定义的变量具有代码块作用域,从该变量定义的地方到包含该定义的代码块的结尾该变量均可见。

传统上,具有代码块作用域的变量都必须在代码块的开始处进行声明,c99放宽了这一规则,允许在代码块的任何位置声明变量,譬如说for循环的控制部分,类似的还有while循环、do while循环等。

以for循环为例:

for(int i = 0; i < 100; i++) ;

 对于变量i来说,只在for循环中可见,离开了for循环,i就不可见了。

b.函数原型作用域:适用于函数原型中使用的变量名。函数原型作用域从变量定义处一直到原型声明的末尾。

int test(int a, int b);

以上述声明为例,变量a、b的作用域只有上面这一行声明。这意味着,在处理一个函数原型的参数时,它所关心的只是参数的类型,使用什么名字是无关紧要的。

c.文件作用域:一个在所有函数之外定义的变量具有文件作用域,具有文件作用域的变量从它定义处到包含该定义的文件结尾处都是可见的。文件作用域变量也被称为全局变量。

(2)链接

一个C变量具有下列链接之一:外部链接、内部链接或空链接

a.空链接:具有代码块作用域或函数原型作用域的变量具有空链接,意味着它们是由其定义所在的代码块或者函数原型所私有的。

b.外部链接、内部链接:具有文件作用域的变量可能有内部链接或者外部链接。一个具有外部链接的变量可以在一个多文件程序的任何地方使用,一个具有内部链接的变量可以在一个文件的任何地方使用。

如何区分外部链接和内部链接呢?声明前面有无static。

(3)存储时期

一个C变量具有以下两种存储时期之一:静态存储时期和自动存储时期

静态存储时期:如果一个变量具有静态存储时期,它在程序执行期间将一直存在,具有文件作用域的变量具有静态存储时期;

自动存储时期:具有代码块作用域的变量一般具有自动存储时期。在程序进入定义这些变量的代码块时,会为这些变量分配内存,当推出这个代码块时,分配的内存将被释放。

  

下面介绍几种变量:

(1)自动变量

属于自动存储类的变量具有自动存储时期、代码块作用域和空链接,默认情况下,在代码块和函数的头部定义的任何变量都属于自动变量。然而,也可以像下面所示显式地使用关键字auto

int main()
{
auto int a;
}

为了有意覆盖一个外部函数定义时,或者为了表明不能将变量改变成其他存储类的时候,可以使用auto。

自动变量的初始化:除非显式地初始化自动变量,否则它不会被自动初始化,如果未初始化,它的初值是先前占用分配给它的空间的任意值。

(2)寄存器变量

通常的变量被存储在计算机内存中,如果幸运的话可以被存储在CPU寄存器中,可以比普通变量更快地被访问和操作。因为寄存器变量多是被存在一个寄存器中而非内存中,因此无法获得寄存器变量的地址,和自动变量一样,它们都具有代码块作用域、空链接以及自动存储时期。

使用关键字register可以声明寄存器变量,但是即使声明了,变量也不一定会被存在寄存器中。

(3)具有代码块作用域的静态变量

这种变量是具有代码块作用域,兼具静态存储的局部变量。这些变量和自动变量具有相同的作用域,但当包含这些变量的函数完成工作时,它们并不消失。这些变量具有代码块作用域,空链接,但是却有静态存储时期,从一次函数调用到下一次调用,计算机都记录着它们的值,这样的变量通过存储类说明符static在代码块内声明创建。

(4)具有外部链接的静态变量

具有外部链接的静态变量具有文件作用域、外部链接和静态存储时期。这一变量被称为外部变量。把变量的定义声明放在所有函数之外,即创建了一个外部变量。如果其他文件使用该外部变量,则需要extern关键字来再次声明它。

外部变量可以被显式地初始化,但是不同于自动变量,如果不对外部变量进行初始化,它们会被赋值为0。外部变量只可以用常量表达式来初始化文件作用域变量。

具有extern关键字是一个引用声明而非定义声明,引用声明不会分配空间。

(5)具有内部链接的静态变量

这种存储类的变量具有静态存储时期、文件作用域以及内部连击,通过使用存储类说明符static在所有函数外部进行定义来创建一个这样的变量。

下面是两个类型限定词:const和volatile

(1)类型限定词const:如果变量声明中带有关键词const,则不能通过赋值、增量或减量运算来改变该变量的值,只可以通过初始化进行赋值

指针使用const有以下两种情况:

const float *pf //pf指向一个常量浮点数值,但是pf本身的值可以改变,譬如说,它可以指向另外一个const值

const * float pt; //pt是一个常量指针,它必须指向同一个地址,但所指向的值可以改变

const float * const ptr; //ptr必须总是指向同一个位置,并且它指位置存储的值也不能改变

这种新关键字的一种常见用法是声明作为函数形式参数的指针,这样指针只是让函数访问值。

如果在文件之间使用const数据,可以使用两个策略:

a.遵循外部变量的惯用规则:在一个文件中进行声明,在其他文件中进行引用声明(关键字extern)

b.将常量放在一个include文件中,譬如说constant.h。而且还必须是静态外部存储类:如果不使用关键字static,在多个文件中都包含头文件,导致每个文件都有同一标识符的定义声明(有些编译器不允许这样做)。

(2)类型限定词volatile:

限定词volatile告诉编译器该变量除了可被程序修改以外还可被其他代理改变,典型地,它被用于硬件地址和其他并行程序共享的数据。

存储类、链接和内存管理(c prime plus)的更多相关文章

  1. 《C prime plus (第五版)》 ---第12章 存储类.链接和内存管理

    12-1:存储类: 1.作用域: 代码块作用域,函数原型作用域和文件作用域. 2.链接:分为外部链接,内部链接和空链接.代码块作用域和函数原型作用域都是空连接,意味着是私有的.而文件作用域的变量可能是 ...

  2. C Primer Plus--C存储类、链接和内存管理之存储类(storage class)

    目录 存储类 作用域 链接 存储时期 自动变量 寄存器变量 具有代码块作用域的静态变量 具有外部链接的静态变量 extern关键字 具有内部链接的静态变量 多文件 存储类 C为变量提供了5种不同的存储 ...

  3. C语言中存储类别、链接与内存管理

      第12章 存储类别.链接和内存管理 通过内存管理系统指定变量的作用域和生命周期,实现对程序的控制.合理使用内存是程序设计的一个要点. 12.1 存储类别 C提供了多种不同的模型和存储类别,在内存中 ...

  4. 【C语言学习笔记】存储类、链接和内存管理

    因为对内存管理部分一直没有很清楚的思路,所以一直在找资料想系统看一下这部分的内容.在C primer plus里看到了这一章,虽然大多都是心知肚明的东西,但是还是很多概念性系统性的东西让我眼前一亮,把 ...

  5. C Primer Plus--C存储类、链接和内存管理之动态分配内存及类型限定词

    目录 存储类说明符 存储类和函数 动态分配内存 malloc函数 free函数 calloc函数 动态分配内存的缺点 C类型限定关键字 constant定义全局常量 volatile关键字 restr ...

  6. C Primer Plus之存储类、链接和内存管理

    存储时期即生存周期——变量在内存中保留的时间 变量的作用域和链接一起表明程序的哪些部分可以通过变量名来使用该变量. 注意:生存期和作用域是两个不同的概念. 作用域    作用域描述了程序中可以访问一个 ...

  7. C中存储类、链接和内存管理

    在C语言中,有5种不同的存储类型,即存储类.在介绍存储类之前,需要首先简单介绍几个术语.如下: 作用域:描述程序中可以访问一个标识符的一个或多个区域.一个C变量的作用域可以是代码块作用域.函数原型作用 ...

  8. 【C语言学习】《C Primer Plus》第12章 存储类、链接和内存管理

    学习总结 1.作用域可分为代码块作用域.函数原型作用域或者文件作用域. 代码块作用域例子: { for(int i=0;i<10;i++){  //C99允许 …  //i的作用域 } ... ...

  9. CPrimer Plus第12章 存储类、链接和内存管理随笔

    被static修饰的属于内部链接,不可被外部程序文件所使用一般而言,全局变量(文件作用域变量)具有静态存储期,局部变量(代码块作用域变量)具有自动存储期寄存器变量不能使用地址运算符因为被static修 ...

随机推荐

  1. 如何进行 Python性能分析,你才能如鱼得水?

    [编者按]本文作者为 Bryan Helmig,主要介绍 Python 应用性能分析的三种进阶方案.文章系国内 ITOM 管理平台 OneAPM 编译呈现. 我们应该忽略一些微小的效率提升,几乎在 9 ...

  2. leetCode题解之寻找一个数在有序数组中的范围Search for a Range

    1.问题描述 Given an array of integers sorted in ascending order, find the starting and ending position o ...

  3. [WSUS] Windows Server Update Service 更新后,出现错误不能连接

    执行以下命令:C:\Program Files\Update Services\Tools\wsusutil postinstall /servicing 参考:http://www.urtech.c ...

  4. Entity Framework工具POCO Code First Generator的使用

    在使用Entity Framework过程中,有时需要借助工具生成Code First的代码,而Entity Framework Reverse POCO Code First Generator是一 ...

  5. [控件] BookTextView

    BookTextView 效果 说明 1. 支持富文本 2. 支持自定义view 3. 支持阅读百分比 源码 https://github.com/YouXianMing/UI-Component-C ...

  6. Win7如何设置多用户同时远程登录

    有时候服务器是Win7系统的时候,远程登录桌面时,即使登录的是不同的管理账号,还是会把远程登录的人给记下来.即不同的账号只能同时存在一个会话窗.本文教大家如果设置Win7让两个账号的两会话同时存在,且 ...

  7. Laravel 实践之路: 数据库迁移与数据填充

    数据库迁移实际上就是对数据库库表的结构变化做版本控制,之前对数据库库表结构做修改的方式比较原始,比如说对某张库表新增了一个字段,都是直接在库表中执行alter table xxx add .. 的方式 ...

  8. c++程序员学习go

    作为一个c++程序员学习go编程的笔记.首先声明本人文笔太差,当你阅读一点觉得实在无法阅读下去时请移步. 下载安装go,安装完毕后会增加系统环境变量path内容指定go程序所在目录,可以打开cmd输入 ...

  9. 团队作业4(Alpha版本)

    项目名称:音乐播放器 项目成员: 张慧敏(201421122032) 苏晓薇(201421031033) 欧阳时康(201421122050) 会议记录:  主要讨论任务的分配和实现过程中已实现和未实 ...

  10. 【转载】 socket recv 和 read

    转自: http://blog.csdn.net/rankun1/article/details/50488989 send函数工作原理: send函数只负责将数据提交给协议层. 当调用该函数时,se ...