C/C++中的const
const是C和C++中的关键字,但是两者的const并不是完全相同的。其实在C语言中一开始只是用#define来表示常量,后来才引进C++中的const。那既然都有了#define,为什么还要再增加const呢?因为const比起#define有以下优点:
- 明确指定类型
- 灵活限制作用域
- const可用于更复杂的数据类型,如数组、结构体等等
- 从汇编角度看,const定义常量只是给出了对应的内存地址,而#define给出的是立即数。所以const更节省程序空间,且在编译期没有存储于读内存的操作,效率高
一、那const定义的数据到底是常量还是只读变量?
1 const int num = 10; 2 char name[num] = {0};
分别把两句代码拿到C和C++编译器上编译,C++编译成功,无警告;C的则报错:“error C2057: 应输入常量表达式”。这是因为,编译器要求数组的大小必须由常量表达,而在C中const只是把变量修饰成只读变量,也就是说只不过是变量的值不允许修改而已。在C中,常量应该用enum或#define表达。很明显,C++中const定义出的是常量。
二、const定义的数据占不占内存?
对于C来说很简单,#define定义的编译器作为立即数处理,放在代码区;const定义的是只读变量,自然占内存。
对于C++,网上有一段话是这么解释的:“const常量是否占据内存取决于是否有引用该常量地址的代码。若没有引用其地址,则编译器不会为其分配空间”。
1 const int a = 10; 2 int *b = (int*)&a; 3 *b = 20; 4 cout << a << " , " << &a << endl 5 << *b << " , " << b << endl;
在vc++2008或g++4.6.1上运行结果都是a = 10, b = 20,地址相同(网上有的帖子说g++运行结果是a = 20,可能是版本较旧所致)。这说明,虽然const常量对应的实际内存已经配修改(这中修改属于未定义行为,即不同编译器可能后不同处理,不能确定后果,所以一般情况下不要这么写),应该是编译器在预编译期已经把a替换成了10。
这又涉及到了一个新的编译术语:常量折叠(const folding)。简单地理解就是编译器对简单的const常量进行优化,在预编译期像#define一样进行替换,保证了const常量不受破坏。这也解释了为什么没用引用const常量地址时,编译器不会为其分配空间。
posted on 2012-05-19 16:27 JacobChen2012 阅读(1037) 评论(1) 编辑 收藏 举报