简谈const限定符

const修饰的数据类型是常量类型,常量类型的对象和变量在定义初始化后是不能被更新的。其实只用记住这一个概念,就可以明白const操作对象的方法。

1)定义const常量

最简单的:

const int a = 1;

a = 2; (错误:a为const常量,在初始化后不能再进行改变)

而且由于这个性质,如果在定义const int a时未进行初始化,会产生编译错误。因为在程序过程中不能对const常量进行修改。而由于const限定符的只读属性,可以避免对程序数据的误操作。

2)const与define

结论:const常量能节省空间,从而避免不必要的内存分配。

阐述原因:

#define A 5

const int B = 5;

int a = A;(在编译期间进行宏替换,为A分配内存)

int b = B;(为B分配内存,初次分配后不会再分配内存)

int aa = A;(A再次分配内存)

int bb = B;(B没有内存分配)

这里define给出的是一个立即数,所以define定义的常量在内存中有若干拷贝。但const常量在程序运行过程中只有一份拷贝。

编译器通常不会为普通const常量分配存储空间,而是将他们保存在符号表中,这就是使得它成为编译期间的常量,没有了存储和读内存的操作,使得效率提高。

3)指向const对象的指针

这里可以这样理解:const后面跟上int,表示const修饰的是int数据类型,即指针指向的内容是被const限定的,不能被修改。

比如:

int a = 1;

int b = 2;

const int *ptr = &a;

这里ptr是一个指向int型的const对象指针,const限定的是ptr指向的对象(int型数据),而不是ptr本身。

所以:

*ptr = 10(错误,不能直接更新ptr指向的内容)

ptr = &b(正确,因为ptr本身并不受const的限定,ptr作为指针可以指向其他内存单元)

补充一点:

普通的指针变量是能够作为左值被赋值修改的。

比如:

int *p = &a;(*p在程序运行过程中能被修改,从而影响到a中数据的改变)

所以:

一个普通指针变量作为左值时,其右值不能是一个const常量。

比如:

const int c = 3;

int *p = &c(错误。这个其实也很好理解,*p可以随意改,那c的值也会被随意改,不满足const的性质)

实际程序中,指向const的指针常常用作函数的形参。将形参定义为指向const的指针,以此来确保传递给函数的实际对象在函数中不会因为形参而被修改。

4)const指针

这个可以和3)对应理解:const后面跟上的指针变量,指针表示地址,则const指针限定了指针本身不能被更新,但指针指向的对象可以被更新(上述3)是限定数据不能更新,指针本身可以更新,正好相反)

比如:

int a = 1;

int b = 2;

int *const ptr = &a;(首先定义const指针指向a)

如果在程序运行过程中进行如下操作:

ptr = &b(错误:因为ptr是一个const指针常量,其在运行过程中不能被更新,即不能再指向其他的内存单元)

*ptr = 3;(正确:因为*ptr是指针指向的对象,其不受const的限定,能够被更新。更新后,a的值为3)

5)指向const对象的const指针

这个就是上述3)和4)的结合。const既限定了指针,又限定了指针指向的对象。

比如:

const int a = 1;

const int *const ptr = &a;

ptr一经初始化完毕后,就不能再指向其他内存单元,也不能被修改其指向内存单元(a的地址)的数据。但a自身可以被定义为普通int型,a可以进行更新。

6)关于typedef和const指针的一个误区

typedef能够用作类型替换,类似于#define。

一个误区是:

typedef string *pstring;

const pstring ptr;

上述ptr是一个什么类型。很容易想到的是:替换pstring,变为const string *ptr。则ptr是一个指向string类型的const对象,即const修饰string数据类型。

实际不然:

看const pstring ptr。在这个里面const修饰的是pstring,而pstring是一个string类型的指针。所以在程序运行过程中,const依然应该修饰一个指针,而不是一个string对象。正确的扩展应为:

strng const *ptr;

出现这个问题的原因在于:对于const常量的表示,string const s1和 const string s2,s1和s2都是等价的类型,即const限定符即可以放在类型前也可以放在类型后。

原文地址:https://www.cnblogs.com/scu-cjx/p/8309082.html