您的位置:首页 > 编程语言 > C语言/C++

读c语言深度剖析 -- 闲谈const(3)

2011-06-23 15:02 267 查看
const 常量折叠




现象及原因解释如下
const int i = 3;
int * p = (int*)&i; //让p指向与i相同的内存空间
(*p)++; // 本应该 i 的值也改变,实际却没有,这就是常量折叠.
"常量折叠"就是在编译器进行语法分析的时候,将常量表达式计算求值,并用求得的值来替换表达式,放入常量表。可以算作一种编译优化。
在这里只是改了这个地址的内容,但是 i 还是3,
因为编译器在优化的过程中,会把碰见的const全部以内容替换掉 (跟宏很像: #define PI 3.1415926,用到PI时就用3.1415926代替)
这个出现在预编译阶段;但是在运行阶段,它的内存里的东西确实改变了、、、
编译器会为常量分配地址,但是在使用常量的时,常量会被一立即数替换
这么做的原因是出于对const数据的保护, 防止被破坏性修改, 这个例子也再一次说明指针的灵活性, 大家使用时一点要注意.

常量折叠,就是类似于c语言中的宏定义。
#define X 5
那么程序中任何出现X的地方都用5代替,X是不需要存储空间的,这叫宏展开。

对于c++中
const int X = 5;
那么,如果没对X取地址或其他用到X存储空间相关的操作,那么X是不分配储存空间的,
编译期间直接进行常量折叠,把程序中的X均用5代替。
常量折叠 分为可以常量折叠的常量和不可以常量折叠的常量
例如
const int a = 8;
cout < < a < < endl;
经过编译器扫描后,变为:
cout < < 8 < < endl;

常量一般分为两种:可以常量折叠的常量和不可以常量折叠的常量。下面具个不可以常量折叠的常量的例子:
int test(){ return 8; }
const int a = test();//常量a不可以常量折叠
cout < < a < < endl;//由于a不可以常量折叠,所以经过编译器扫描之后仍然是“cout < < a < < endl;”
切记。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息