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

xiaoxiao2021-02-28  60

C Primer Plus》读到12章,我的C语言复习进展的挺不错。这一章介绍存储类、连接和内存管理,可以说是重中之重。C5种存储类:自动——在一个代码块内(或在一个函数头部作为参量)声明的变量,无论有没有存储类修饰符auto,都属于自动存储类。该类具有自动存储时期、代码块的作用域和空链接(no linkage),如未初始化,它的值是不确定的(java要求局部变量必须初始化)寄存器—— 在一个代码块内(或在一个函数头部作为参量)使用修饰符register声明的变量属于寄存器存储类。该类与自动存储类相似,具有自动存储时期、代码块作 用域和空连接,声明为register仅仅是一个请求,而非命令,因此变量仍然可能是普通的自动变量,但是仍然无法获取地址。。如果没有被初始化,它的值 也是未定的。静态、空链接——在一个代码块内使用存储类修饰符static声明的局部变量属于静态空连接存储类。该类具有静态存储时期、代码块作用域和空链接,仅在编译时初始化一次。如未明确初始化,它的字节将被设定为0.静态、外部链接——在所有函数外部定义、未使用static修饰的变量属于静态、外部链接存储类。改类具有静态存储时期、文件作用域和外部链接,仅在编译时初始化一次。如未明确初始化,它的字节也被设定为0.静态、内部链接——与静态、外部链接存储类不同的是,它使用static声明,也定义在所有函数外部,但是具有内部链接(仅能被与它在同一个文件的函数使用),仅在编译时初始化一次。如未明确初始化,它的字节也被设定为0.两个关键字:volatilerestrict,两者都是为了方便编译器的优化。volatile告诉编译器该被变量除了可被程序修改意外还可能被其他代理修改,因此,当要求使用volatile 声明的变量的值的时候,系统总是重新从它所在的内存读取数据,而不是使用寄存器中的缓存。比如val1=x;val2=x; 果没有声明volatile,系统在给val2赋值的时候可能直接从寄存器读取x(假定聪明的编译器优化了),而不是从内存的初始位置,那么在两次赋值之 间,x完全有可能被被某些编译器未知的因素更改(比如:操作系统、硬件或者其它线程等)。如果声明为volatile,编译器将不使用缓存,而是每次都从 内存重新读取xrestrictc99引入的,它只可以用于限定指针,并表明指针是访问一个数据对象的唯一且初始的方式restrict表示只能通过它限定的指针访问该指针所指向的对象。),考虑下面的例子: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。有兴趣的看看这个

 

 

restrictC99版新增加的关键字! 如下: C99   中新增加了   restrict   修饰的指针:     restrict   修饰的指针是最初唯一对指针所指向的对象进行存取的方法,仅当第二个指针基于第一个时,才能对对象进行存取。对对象的存取都限定于基于由   restrict   修饰的指针表达式中。   restrict   修饰的指针主要用于函数形参,或指向由   malloc()   分配的内存空间。restrict   数据类型不改变程序的语义。   编译器能通过作出   restrict   修饰的指针是存取对象的唯一方法的假设,更好地优化某些类型的例程。 [典型例子]   memcpy()     C99   中,restrict   可明确用于   memcpy()   的原型,而在  C89 中必须进行解释。   void   *memcpy(void   *restrict   str1,   const   void   *restrict   str2,   size_t   size);   /*   通过使用   restrict   修饰   str1     str2   来保证它们指向不重叠的对象   */

<script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script> 阅读(220) | 评论(0) | 转发(0) | 0

上一篇:task _struct注释

下一篇:LINUX多路复用select,poll,epoll

相关热门文章 linux 常见服务端口xmanager 2.0 for linux配置【ROOTFS搭建】busybox的httpd...openwrt中luci学习笔记Linux里如何查找文件内容... 给主人留下些什么吧!~~ 评论热议
转载请注明原文地址: https://www.6miu.com/read-57459.html

最新回复(0)