C语言的5种存储类以及关键字volatile、restrict

《C Primer Plus》读到12章,我的C语言复习进展的挺不错。这一章介绍存储类、连接和内存管理,可以说是重中之重。
C的5种存储类:
自动——在一个代码块内(或在一个函数头部作为参量)声明的变量,无论有没有存储类修饰符auton,都属于自动存储类。该类具有自动存储时期、代码块的作用域和空链接(no linkage),如未初始化,它的值是不确定的(java要求局部变量必须初始化)

寄存器——在一个代码块内(或在一个函数头部作为参量)使用修饰符register声明的变量属于寄存器存储类。该类与自动存储类相似,具有自动存储时期、代码块作用域和空连接,声明为register仅仅是一个请求,而非命令,因此变量仍然可能是普通的自动变量,但是仍然无法获取地址。。如果没有被初始化,它的值也是未定的。

静态、空链接——在一个代码块内使用存储类修饰符static声明的局部变量属于静态空连接存储类。该类具有静态存储时期、代码块作用域和空链接,仅在编译时初始化一次。如未明确初始化,它的字节将被设定为0.

静态、外部链接——在所有函数外部定义、未使用static修饰的变量属于静态、外部链接存储类。改类具有静态存储时期、文件作用域和外部链接,仅在编译时初始化一次。如未明确初始化,它的字节也被设定为0.

静态、内部链接——与静态、外部链接存储类不同的是,它使用static声明,也定义在所有函数外部,但是具有内部链接(仅能被与它在同一个文件的函数使用),仅在编译时初始化一次。如未明确初始化,它的字节也被设定为0.

两个关键字:volatile和restrict,两者都是为了方便编译器的优化。

volatile告诉编译器该被变量除了可被程序修改意外还可能被其他代理修改,因此,当要求使用volatile 声明的变量的值的时候,系统总是重新从它所在的内存读取数据,而不是使用寄存器中的缓存。比如
val1=x;
val2=x;
如果没有声明volatile,系统在给val2赋值的时候可能直接从寄存器读取x(假定聪明的编译器优化了),而不是从内存的初始位置,那么在两次赋值之间,x完全有可能被被某些编译器未知的因素更改(比如:操作系统、硬件或者其它线程等)。如果声明为volatile,编译器将不使用缓存,而是每次都从内存重新读取x。

而restrict是c99引入的,它只可以用于限定指针,并表明指针是访问一个数据对象的唯一且初始的方式,考虑下面的例子:
int ar[10];
int * restrict restar=(int *)malloc(10*sizeof(int));
int *par=ar;

这里说明restar是访问由malloc()分配的内存的唯一且初始的方式。par就不是了。
那么:
for(n=0;n<10;n++)
{
   par[n]+=5;
   restar[n]+=5;
   ar[n]*=2;
   par[n]+=3;
   restar[n]+=3;
}
因为restar是访问分配的内存的唯一且初始的方式,那么编译器可以将上述对restar的操作进行优化:
   restar[n]+=8;

而par并不是访问数组ar的唯一方式,因此并不能进行下面的优化:
   par[n]+=8;
因为在par[n]+=3前,ar[n]*=2进行了改变。使用了关键字restric,编译器就可以放心地进行优化了。这个关键字据说来源于古老的FORTRAN。有兴趣的看看这个

文章转自庄周梦蝶  ,原文发布时间2007-08-04

时间: 2023-01-05

C语言的5种存储类以及关键字volatile、restrict的相关文章

解析C++中的5个存储类的作用_C 语言

存储类定义 C++ 程序中变量/函数的范围(可见性)和生命周期.这些说明符放置在它们所修饰的类型之前.下面列出 C++ 程序中可用的存储类: auto register static extern mutable 存储类说明符可以分为两个存储类:自动存储类(autmatic storage class)和静态存储类(static storage class).关键字auto和regtster用来声明自动存储类变量.这种变量在进入声明的块时生成,在块活动期间存在,在退出这个块时删除. 只有变量能作

C语言 存储类详解及示例代码_C 语言

C 存储类 存储类定义 C 程序中变量/函数的范围(可见性)和生命周期.这些说明符放置在它们所修饰的类型之前.下面列出 C 程序中可用的存储类: auto register static extern auto 存储类 auto 存储类是所有局部变量默认的存储类. { int mount; auto int month; } 上面的实例定义了两个带有相同存储类的变量,auto 只能用在函数内,即 auto 只能修饰局部变量. register 存储类 register 存储类用于定义存储在寄存器

《Java程序员面试秘笈》—— 面试题5 用自己的语言描述Java中的类和对象

面试题5 用自己的语言描述Java中的类和对象 下列关于对象的哪一种说法是正确的?请选择一个正确的答案. (a)对象是可以对其进行实例化从而得到类的东西. (b)对象是类的实例. (c)对象是一种蓝本,据此可以创建抽象的具体实现. (d)对象是指向属性的引用. (e)对象是一种变量. 考点:该面试题考察求职者对于Java类和对象的理解. 出现频率: [面试题解析] 1.类 在处理复杂事物的时候,用到的一种基本手段就是抽象.抽象的目的就是区别事物之间的本质和不同,面向对象编程(OOP)的实质就是利

[Android]Android数据的四种存储方式

Context ctx=MainActivity.this; ContentResolver resolver =ctx.getContentResolver(); Uri uri=Uri.parse("content://com.example.androidtestdemo"); Cursor c = resolver.query(uri, null, null, null, null); c.moveToFirst(); while(!c.isAfterLast()){ for(

家庭安防摄像头储存信息量大 哪种存储方式更加靠谱

 随着谷歌以5.55亿美元的价格收购美国家庭监控摄像头创业公司Dropcam,家庭监控类产品概念被引爆,一波家庭智能摄像头的浪潮也在中国迅速掀起.百度.阿里.腾讯为首的中国互联网巨头纷纷推出自己的家庭智能摄像头,就连以手机业务为主的小米和以专注安全领域的360也都相继推出了自己的家庭智能摄像头产品,一时国内家庭智能摄像头市场呈现百花齐放之景. 而随着人们生活水平的提高,越来越多的人开始意识到了家中在没有人的时候自己财产的安全问题.而家用监控摄像机也随着需求的产生出现在了人们的视野中.如果你担心家

Android通过&quot;记住密码&quot;功能学习数据存储类SharedPreferences详解及实例_Android

SharedPreferences是Android中存储简单数据的一个工具类.可以想象它是一个小小的Cookie,它通过用键值对的方式把简单数据类型(boolean.int.float.long和String)存储在应用程序的私有目录下(data/data/包名/shared_prefs/)自己定义的xml文件中.  一.简介 它提供一种轻量级的数据存储方式,通过eidt()方法来修改里面的内容,通过Commit()方法来提交修改后的内容.  二.重要方法 public abstract boo

利用数据寿命增加基于闪存的存储类存储器的使用寿命

 本文提出在闪存闲置时利用保留时间的能力,以提高SSD中SLC的使用寿命.主要思想是,作为大多数I / O数据典型的工作负载不需要大于几天的保留时间,我们可以在单元格中使用多个部分程序状态,并且每两个状态每次存储一位数据.所以我们可以在单元中存储多个位(每次一个位),每次写完后并不擦除,这将直接转化为寿命的增强.这里所提出的方案称为密集SLC(D-SLC)闪存设计,可将SSD寿命提高5.1-8.6倍. DENSE-SLC NAND FLASH-BASED SSD 典型的基于闪存的存储类内存(SC

玩转云端存储 安卓云存储类应用推荐

近日,腾讯的跨平台云存储服务"微云"正式上线,同时支持使用网页.Windows客户端和Android客户端登录. 整个国内云存储服务市场也因为腾讯微云的加入而变得更加丰富,而且竞争也会更加激烈.今天笔者为大家挑选几款云存储应用,功能各有差异,也有比较成熟的产品. 玩转云端存储 安卓云存储类应用推荐 腾讯手机管家 腾讯手机管家支持手机杀毒.手机加速.流量监控.骚扰拦截.手机省电以及网盘等功能,为用户提供全面的手机安全与管理功能. 用户可以使用QQ账号登录腾讯手机管家的网盘,在网盘中可批量

Oracle10g数据库的4种存储形式

数据库的存在一定需要有永久性存储方式和介质.Oracle自然也不例外,在Oracle10g中,有4种存储形式,分别是操作系统文件,裸分区,自动存储管理,集群系统OCFS(RAC).下面分别说一下这4种存储形式. 1 操作系统文件. 这种是大家最常用的方式了,也是非商业运行模式(比如开发或者开发阶段的测试环境)下最常用的形式.当大家安装Oracle的时候,如果选用了操作系统文件的存储形式,那么就会把Oracle的数据存储在操作系统中,以文件的形式存在.就好像我们玩某些单机版游戏,你的存档就是操作系