《C Primer Plus》读到12章,我的C语言复习进展的挺不错。这一章介绍存储类、连接和内存管理,可以说是重中之重。C的5种存储类:自动——在一个代码块内(或在一个函数头部作为参量)声明的变量,无论有没有存储类修饰符auto,都属于自动存储类。该类具有自动存储时期、代码块的作用域和空链接(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引入的,它只可以用于限定指针,并表明指针是访问一个数据对象的唯一且初始的方式(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。有兴趣的看看这个。
restrict是C99版新增加的关键字! 如下: 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里如何查找文件内容... 给主人留下些什么吧!~~ 评论热议