const分别在C和C++语言里的含义和实现机制
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了const分别在C和C++语言里的含义和实现机制相关的知识,希望对你有一定的参考价值。
const的含义
简单地说:const在c语言中表示只读的变量,而在c++语言中表示常量.
C语言
const是constant的缩写,是恒定不变的意思,也翻译为常量,但是很多人都认为被const修饰的值都是常量,其实这是不精确的.因为,精确来说应该是只读的变量,其值在编译的时候不能被使用,因为编译器在编译的时候不知道其存储的内容.或许当初这个关键字应该被替换为readonly.
C语言中const定义的变量只是给出了对应的内存地址,而不是像#define一样给出的是立即数,所以,const定义的只读变量在程序运行过程中只有一个备份(因为它是全局的只读变量,存放在静态区),而#define定义的宏变量在内存中有若干个备份.
c++语言:
const是C++中常用的类型修饰符,常类型是指使用类型修饰符const说明的类型,常类型的变量或对象的值是不能被更新的.
C++引入const的初始目的是为了取代预编译指令,消除他的缺点,同时继承它的优点.<缺点:只是简单值和代码的替代,缺乏类型的检测机制,安全性不好;优点有三:1.避免意义模糊的数字出现,清晰程序语义2.方便参数的调整和修改,3.提高程序执行效率,因为不需要为常量分配空间>
问题出来了:为什么const能取代预定义语句?
1. 首先,以const修饰的变量和对象具有不可变性,这是它能取代预定义语句的基础.
2. 第二,很明显,它同样能避免意义模糊的数字定义,也可以方便地进行参数的调整与修改.
3. 第三,c++编译器通常不为普通const常量(普通是指内置类型,不包括结构体等类型)分配存储空间,只是把它们保存在符号表中(注意:c语言中则会为const变量分配存储空间),这使得它们成为了编译期间的常量,没有了存储和读内存的操作,使得它的效率非常高,同时,也是它能取代预定义语句的重要基础.
4. 最后,const定义也能像普通的变量定义一样,它会由编译器对它进行类型的安全检查,消除了预定义语句带来的安全隐患.
我们使用一张表来总结const的作用:
No. |
作用 |
说明 |
参考代码 |
1 |
可以定义const常量 |
|
const int Max = 100; |
2 |
便于进行类型检查 |
const常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查,而对后者只进行字符替换,没有类型安全检查,并且在字符替换时可能会产生意料不到的错误 |
void f(const int i) { .........} |
3 |
可以保护被修饰的东西 |
防止意外的修改,增强程序的健壮性。 |
void f(const int i) { i=10;//error! } |
4 |
可以很方便地进行参数的调整和修改 |
同宏定义一样,可以做到不变则已,一变都变 |
|
5 |
为函数重载提供了一个参考 |
|
class A |
6 |
可以节省空间,避免不必要的内存分配 |
const定义常量从汇编的角度来看,只是给出了对应的内存地址,而不是象#define一样给出的是立即数,所以,const定义的常量在程序运行过程中只有一份拷贝,而#define定义的常量在内存中有若干个拷贝 |
#define PI 3.14159 //常量宏 |
7 |
提高了效率 |
编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高 |
|
const的实现机制
const究竟是如何实现的呢?对于声明为const的内置类型,例如int,short,long等等,编译器会如何实现const的本意?那么对于非内置类型是否也是与内置数据类型一样处理呢,例如对于结构体类型则会怎样处理呢?下面通过几个小例子来说明这些问题:
C语言const示例:
const int i=10;
int *p=(int *)(&i);
*p=20;
printf("i=%d *p=%d \n",i,*p);
猜一猜输出结果是什么? i=20 *p=20
C++语言const示例1:
const int i=10;
int *p=const_cast<int *>(&i);
*p=20;
cout<<"i="<<i<<"*p="<<*p<<endl;
输出结果是 i=10 *p=20
C++语言const示例2:
struct test{
int j;
char tmp;
test()
{
j=30;
tmp=‘a‘;
}
};
int main(int argc, char* argv[])
{
const struct test t1;
int *q=(int *)(&t1.j);
*q=40;
cout<<"j="<<t1.j<<"*q="<<*q<<endl;
return 0;
}
输出结果是 j=40 *q=40
示例结果分析
看到上面三组输出结果,我们可以分析两个问题:
问题1:C语言和C++语言中的const究竟表示什么?
问题2:const的实现机制究竟是怎样的?
问题1,对于const int类型的变量i,C语言中通过指针p修改了值后,i变成了20;而在C++中,通过指针p修改了值后,i仍然是10。
问题2,C++语言中 const struct test的元素j通过指针q被改变了,为何const int 与 const struct test的反应机制不同?
针对问题1,我们知道C语言中const表示只读的变量,既然把const看成是变量,那么其在内存中就会有存储他的空间,并且可以通过指针间接的改变该内存空间的值,当通过指针p改变该内存中的值后,再获取i的值的时候,会访问该空间,得到的是被改变后的值。而C++把const看做常量,编译器会使用常数直接替换掉对i的引用,例如cout<<i; 会理解成cout<<10; 并不会去访问i的内存地址去取数据,这里有点像是C语言里的宏#define i 10。因此C++里i会输出10,而*p会输出20.
针对问题2,C++语言中只是对于内置数据类型做常数替换,而对于像结构体这样的非内置数据类型则不会。因为结构体类型不是内置数据类型,编译器不知道如何直接替换,因此必须要访问内存去取数据,而访问内存去取数据必然会取到被指针q改变后的值,因此会造成与C++中const int类型完全不一样的处理模式。
参考文章:http://blog.csdn.net/chenhuajie123/article/details/9221149
以上是关于const分别在C和C++语言里的含义和实现机制的主要内容,如果未能解决你的问题,请参考以下文章
用java 、C++、 C 或者VB 中任何一种语言实现两个函数encode()和decode(),分别实现对字符串的变换和复原.