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

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++是错误的。

你可能感兴趣的:(读c语言深度剖析 -- 闲谈const(1))