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

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

2011-06-23 13:53 253 查看
const关键字也许该被替换为readolny

1 const修饰的只读变量
定义const只读变量(一定不要与常量混淆),具有不可变性。
例如:
const int Max=100;
int Array [Max];
这里请在Visual C++ 6.0里分别创建.c文件和.cpp文件测试一下。你会发现在.c文件中,
编译器会提示出错,而在.cpp文件中则顺利运行。为什么呢?我们知道定义一个数组必须指
定其元素的个数。这也从侧面证实在C语言中,const修饰的Max仍然是变量,只不过是只读属性罢了;而在C++里,扩展了const的含义
1)、这个问题讨论的是常量”与“只读变量”的区别。
常量肯定是只读的,例如5,"abc",等,肯定是只读的,因为常量是被编译器放在内存中的只读区域,当然也就不能够去修改它。
“只读变量”则是在内存中开辟一个地方来存放它的值,只不过这个值由编译器限定不允许被修改。C语言关键字const就是用来限定一个变量不允许被改变的修饰符。上述代码中变量Max被修饰为只读变量,可惜再怎么修饰也不是常量。而ANSI C规定数组定义时长度必须是“常量”,“只读变量”也是不可以的。
2)、注意:(常量!=不可变的变量,但在标准C++中,这样定义的是一个常量,这种写法是对的),实际上,根据编译过程及内存分配来看,这种用法本来就应该是合理的,只是ANSI C对数组的规定限制了它。
3)、那么,在ANSI C语言中用什么来定义常量呢?答案是enum类型和#define宏,这两个都可以用来定义常量。

注意:const修饰的只读变量必须在定义的同时初始化(网上资料)
1因为const变量不能在运行的过程中修改,所以如果在定义时没有初始化,那么就没意义了
2如果不在声明的时候初始化而在其他地方修改,岂不违背了“只读”的意思
3在定义的时候就把它的内存空间给限制死了,要是不初始化,那块区域永远就是那个样子了(C语言标准规定的)

2 修饰一般变量
int const i=2;或const int i=2;
3 修饰数组
定义或说明一个只读数组可采用如下格式:
int const a[5]={1,2,3,4,5};或constinta[5]={1,2,3,4,5};
4 修饰引用
const double & v; 该引用所引用的对象不能被更新
const是为了不让修改,引用是为了避免复制
很多对象如果用传值,会复制一份,很占地方,用引用又怕函数修改它,所以用了常引用
5 修饰字符串
看下边代码有什么问题?  
char *p = "i'm hungry!";  p[0]= 'I';  
分析:  
上面的代码可能会造成内存的非法写操作。分析如下,"i'm hungry"实质上是字符串常量,而常量往往被编译器放在只读的内存区不可写。p初始指向这个只读的内存区,而p[0] = 'I'则企图去写这个地方,编译器当然不会答应。  
再问char a[3] = "abc"合法吗?使用它有什么隐患?  
分析:  
在标准C中这是合法的,(c++中是不可以这样写的)但是它的生存环境非常狭小;它定义一个大小为3的数组,初始化为"abc",注意,它没有通常的字符串终止符'\0',因此这个数组只是看起来像C语言中的字符串,实质上却不是,因此所有对字符串进行处理的函数,比如strcpy、printf等,都不能够被使用在这个假字符串上。修饰typedef定义的类型
代码如下哪一个语句是错误的呢?   
typedef char * pStr;  
char string[4] = "abc";  
const char *p1 = string;  
const pStr p2 = string;  
p1++;  
p2++;  
分析:
问题出在p2++上。  
1)、const使用的基本形式:const char m; (模板)  限定m不可变。  
2)、替换1式中即 *p1->m;故限定*p1不可变,当然p1是可变的,因此p1++是对的。  3)、替换2式即, p2->m , const newType m;限定m不可变,问题中的charptr就是一种新类型,因此问题中p2不可变,p2++是错误的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息