C++/C 中const 的区别以及const与一级指针,二级指针的结合

首先,给大家声明一点在C语言中const修饰的变量称为常变量,即本质上还是变量。

C编译器和C++编译器对const的解释是完全不一样的。如下面这串代码,(在C编译器中运行是没错的)

const int a = 10;
const int b;

但是在C++中第二句就会报错。原因在于,C编译器编译常变量(即const修饰的量)和普通变量是没区别的。唯一的区别在于const修饰的量不可以作为左值。而在C++中,编译二者有很大区别。相信大家都知道在编译阶段,编译器会给变量生成符号,而给普通变量生成的是global类型而常量生成的符号是local类型。由于在C++中由const修饰的量是常量,定义的时候就必须要初始化。其次在编译阶段对常量直接进行替换。而不是在运行阶段赋值。下面的代码将说明这个特点。

方式一:
int a = 10;
int *p = &a;
*p=20;
cout<<a<<" "<<*p<<endl;

方式二:
const int a = 10;
int *p = (int *)&a;
*p = 20;
cout<<a<<" "<<*p<<endl;

读者可以在自己的编译器上试一下(文件要以.cpp结尾哦),我的编译器是VS2015,方式一是大家所熟知的,结果是20,20.

但是方式二的结果就会出乎某些读者的意料,结果是10  20。原因何在呢?

其实答案就在前面的叙述中,因为在C++中,编译阶段就会将cout语句中的a直接替换成10,但并不是说没有给常量a开辟空间。

 

下面就该谈谈 一级指针 和 const 的结合了。

首先,const永远修饰的是离它最近的那个类型!类型!类型!(重要的事情说三遍)

就比如 :

const int *p;
int const *p;
int *const p;
const int *const p;

读者若能区分这几者的区别下面的部分内容也可以当做复习一下!!!

 第一个和第二个其实是没区别的 离const最近的类型是int,因此const修饰的表达式是*p。感兴趣的读者可是验证一下,引入typeinfo头文件,typeid(); 第三个const修饰的类型是int *,从而修饰的表达式是p,最后一句第一个const修饰的类型是int,第二个修饰的类型是int *,那么前一个const修饰 表达式 *p,后一个const修饰的是p。

A:
int a = 10 ;
const int* p= &a;
B:
const int a=10;
const int* p=&a;
C:
int a = 10;
int *const p =&a;

判断上述三个选项的正误并说明理由?

A正确,原因在于&a就相当于一个int *,把一个普通变量的地址给到一个指向常量的指针是完全没有问题的,而且更安全,不能通过其地址对其进行操作。反着来是不行的。同理B也就得出结论了。再就是C,C也是完全ok的,const修饰的表达式是p,也就是说初始化以后,p再也不能作为左值。

下面再来看一道经典的笔试题/面试题

int a = 10;
const int *p=&a;
int *q = p;

这几行代码是否有误?如果错误,说明理由?

答案是肯定的,很多读者可能也会猜到,这么问问题,肯定有坑。没错,就是有坑。正确的回答方式应该是 第三句出错了,出错的原因是,当编译器在处理p,q时,只会根据其类型来予以区分,p在这里是int const *类型,也就是说p里面不管存的是变量的地址还是常量的地址,编译器就把它当做整形常量的地址来处理,因此当你企图将一个常量的地址赋给一个普通指针变量时,编译器就会报错。因为一切将会引起常量地址泄露的操作编译器会将其扼杀在摇篮中。

下面来谈谈const和二级指针的结合

const int **p;
int const **p;
int  *const *p;
int **const p;
const int *const*p;

与上面的分析方法类似,第一个const修饰的是**p,第二个与第一个类似,第三个const修饰*p,第四个修饰p,第五个前面的const修饰的是**p,后面const修饰*p。

下面有几个经典的面试题

A.
int a = 10;
int *p = &a;
const int **q=&p
B.
int a = 10;
int *p=&a;
int *const*q = &p;
C.
int a = 10;
int *p=&a;
int **constq = &p;
D.
int a = 10;
int *const p=&a;
int **q = &p;
E.
int a = 10;
const int *p=&a;
int *const*q = &p;

对const和二级指针结合的题目   只需要注意一点,左右两边类型不匹配就不正确。

首先对于A选项,第三句相当于const int **q  <===   int **p,将二级指针退化成一级指针,即把*q,*p作为整体,const int*是*q的类型,int*是p的类型,前面说过用一个int*类型的值给const int*类型的是ok的。因此A正确

B.一样的分析方法,int *const* q = int **p  ,也即int *const p在定义的 时候能否由  int *q 赋值,答案是肯定的,

C.有一个诀窍----当const右边没有这个符号 ‘*’ 时,const将不作为变量类型中的一个标识符。这里明显q的类型是int**而p也是int**类型,因此C选项正确

后面分析问题的方式和方法也都一样了,我就不在此处过多赘述了。

水平有限,写出来的东西可能会有误,望读者能够有所包容,并以留言的形式告知。

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值