Chinaunix首页 | 论坛 | 博客
  • 博客访问: 142341
  • 博文数量: 33
  • 博客积分: 2520
  • 博客等级: 少校
  • 技术积分: 365
  • 用 户 组: 普通用户
  • 注册时间: 2009-04-10 09:26
文章分类

全部博文(33)

文章存档

2011年(1)

2010年(6)

2009年(26)

我的朋友

分类: C/C++

2009-04-24 16:22:27

C的5种存储类:
自动——在一个代码块内(或在一个函数头部作为参量)声明的变量,无论有没有存储类修饰符auton,都属于自动存储类。该类具有自动存储时期、代码块的作用域和空链接(no linkage),如未初始化,它的值是不确定的(java要求局部变量必须初始化)

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

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

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

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

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

One of the new features in the recently approved C standard C99, is the restrict pointer qualifier. This qualifier can be applied to a data pointer to indicate that, during the scope of that pointer declaration, all data accessed through it will be accessed only through that pointer but not through any other pointer. The ''restrict'' keyword thus enables the compiler to perform certain optimizations based on the premise that a given object cannot be changed through another pointer. Now you''re probably asking yourself, "doesn''t const already guarantee that?" No, it doesn''t. The qualifier const ensures that a variable cannot be changed through a particular pointer. However, it''s still possible to change the variable through a different pointer.


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

而restrict是c99引入的,关键字restrict只用于限定指针;该关键字用于告知编译器,所有修改该指针所指向内容的操作全部都是基于(base on)该指针的,即不存在其它进行修改操作的途径;这样的后果是帮助编译器进行更好的代码优化,生成更有效率的汇编代码。

举个简单的例子


int foo (int* x, int* y)
...{
*x = 0;
*y = 1;
return *x;
}

很显然函数foo()的返回值是0,除非参数x和y的值相同。可以想象,99%的情况下该函数都会返回0而不是1。然而编译起必须保证生成100%正确的代码,因此,编译器不能将原有代码替换成下面的更优版本

int f (int* x, int* y)
...{
*x = 0;
*y = 1;
return 0;
}

啊哈,现在我们有了restrict这个关键字,就可以利用它来帮助编译器安全的进行代码优化了

int f (int *restrict x, int *restrict y)
...{
*x = 0;
*y = 1;
return *x;
}


此时,由于指针 x 是修改 *x的唯一途径,编译起可以确认 “*y=1; ”这行代码不会修改 *x的内容,因此可以安全的优化为

int f (int *restrict x, int *restrict y)
...{
*x = 0;
*y = 1;
return 0;
}


最后注意一点,restrict是C99中定义的关键字,C++目前并未引入;在GCC可通过使用参数" -std=c99"
来开启对C99的支持


中间这段来源于:http://blog.csdn.net/lovekatherine/archive/2007/11/19/1891806.aspx
使用了关键字restric,编译器就可以放心地进行优化了。这个关键字据说来源于古老的FORTRAN。有兴趣的看看。
阅读(728) | 评论(0) | 转发(0) |
0

上一篇:合理规划您的硬盘分区

下一篇:VI

给主人留下些什么吧!~~