Chinaunix首页 | 论坛 | 博客
  • 博客访问: 69399
  • 博文数量: 51
  • 博客积分: 141
  • 博客等级: 入伍新兵
  • 技术积分: 300
  • 用 户 组: 普通用户
  • 注册时间: 2012-02-24 15:50
文章分类

全部博文(51)

文章存档

2012年(51)

最近访客

分类:

2012-03-06 21:22:50

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

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

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

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

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

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

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

restrictc99引入的,它只可以用于限定指针,并表明指针是访问一个数据对象的唯一且初始的方式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   来保证它们指向不重叠的对象   */

阅读(440) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~