首先介绍三个概念:

(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. Android Apk增量更新

    前言 有关APK更新的技术比较多,例如:增量更新.插件式开发.热修复.RN.静默安装. 下面简单介绍一下: 什么是增量更新?   增量更新就是原有app的基础上只更新发生变化的地方,其余保持原样. 与 ...

  2. Pig distinct用法举例

    dst = distinct data:   DISTINCT只能对整个记录(整行)去重,不能在字段级别去重.   触发reduce阶段   data = load 'data'; distinct ...

  3. python中的字符串编码问题——3.各操作系统下的不同编码方式

    各操作系统下的不同编码方式  先看一下 linux,python2.7 >>> B = b'\xc3\x84\xc3\xa8' >>> B.decode('utf- ...

  4. 4.Spring——xml配置文件

    如果使用Maven构建项目,spring在加载xsd文件时总是先试图在本地查找xsd文件(spring的jar包中已经包含了所有版本的xsd文件), 如果没有找到,才会转向去URL指定的路径下载.ap ...

  5. Jmeter入门--脚本录制

    一.Badboy脚本录制(推荐) 下载地址:http://www.badboy.com.au/download/add,下载完成后直接安装即可. Badboy是一个强大的工具,旨在帮助测试和开发复杂的 ...

  6. SQL 中Count()的问题

    假如一张表中有如下的数据: 当使用select Count(*) from TableName表示获取表中数据记录的条数: 有时候可以通过select Count(列名) from TableName ...

  7. EF CodeFirst下的自动迁移

    当我们修改数据模型,添加一个如下字段 再次运行程序,会因为数据库结构与模型不一致而报错 为解决以上错误可以采取以下三种方式 1.  删除数据库,重新运行站点,会重新生成数据库,这样就会丢失数据 2.  ...

  8. windows server 2016部署服务

          绪论 有时候,如果安装系统数量比较多,而且数量较多,人工使用U盘或者光盘安装,效率较低,通过网络可以批量安装. 还可以做到无人安装. PXE PXE(preboot execute env ...

  9. 事后诸葛亮之Alpha十天冲刺之失败总结

    参考自构建之法p341页的模板 首先自己预计了一下,项目gg的可能有百分之50这里面有百分之80是我的责任.冲刺失败我承担主要责任. 1.设想和目标: 1.计划实现类似华为云的小功能之团队合作开发功能 ...

  10. Web 通信 之 长连接、长轮询(转)

    Web 通信 之 长连接.长轮询(long polling) 基于HTTP的长连接,是一种通过长轮询方式实现"服务器推"的技术,它弥补了HTTP简单的请求应答模式的不足,极大地增强 ...