今天在学习C++STL中内置迭代器的过程中,因为声明变量时没有加const关键字,引发了错误,所以想用这篇博客来专门记录平时可能用到的与const有关的问题。
【问题1】平时在使用一个指针来指向一个常量时,可能引发的问题。
#include<stdio.h>
int main()
{
const int a = 10;
int* p = &a;
return 0;
}
这是一个非常经典的例子,a是一个常量,现在使用一个指针p来指向常量a,如果我们不对指针p加以修饰,那么指针p就会有修改a的风险,而我们又知道常量的值是不容许被改变的,因此我们也要给指针p加上const关键字,对其进行限制,使得不能通过p来修改a的值。但问题是const关键字应该加在哪里呢?
const int*p = &a;
int* const p = &a;
第一种,将const加在内置类型int前面,即 const int* p = &a,这样就能限制指针p,使得不能通过指针p来修改其指向的变量a的值,即我们不能改变*p的值。
第二种,将const加载内置类型int后面,即 int* const p = &a,这里是使指针p的指向不能更改,即指针p指向a以后,就不能再指向其它地址了,但可以通过指针p来修改a的值,即我们可以改变*p的值。
那这是为什么呢?我们归结于const关键字可以忽视其右边的所有内置类型。
例如,在const int* p = &a 中,当const关键字忽视其右边的所有内置类型,即int以后,const 直接与*p结合,就变成了 const *p,此时const 直接修饰*p,也就是说*p的值不允许被修改,但p还可以指向不同的地址,只是不允许修改*p的值。而在 int* const p = &a 中,const关键字的右边没有内置类型,const直接与p 结合,就变成了const p,也就是说指针p的指向不能被修改,但其指向内容的值,即*p允许被修改。
综上所述,在这个例子中,我们要选择第一种方法,来避免通过指针p修改a的内容,即
#include<stdio.h>
int main()
{
const int a = 10;
const int* p = &a;
return 0;
}
【问题2】
#include<stdio.h>
int main()
{
int a = 20;
const int b = a;
int c[b] = { 0 };
}
首先这段代码是错误的,因为a是变量,它的值要在运行阶段才能知道,而b是常量,它的值在编译阶段就知道了(或者获取了),所以在 const int b = a 中,b不能获取a的值,此时b就要退化为常变量,当b退化为常变量时,int c[b]就产生了一个语法错误,因为在定义一个数组时,若人为的给定这个数组大小,那么此时的这个大小必须是一个常量,而此时的b是常变量。
我们看到编译器报的错误,与我们分析的结果一致。
【问题3】常引用可以引用不能取地址的数据。
int &p = 5;//错误
const int &p = 5;//正确
第一条语句出现编译错误,原因是文字常量不可寻址,因而无法为文字常量建立引用。
第二条正确的原因是编译器将一个文字常量转化成常变量的过程。在数据区开辟一个值为5的无名整型常变量,然后将引用p与这个整型常变量进行绑定。也就是说此时p引用的是一个临时量。
常量和常变量的区别:https://zhidao.baidu.com/question/48459859.html
https://www.jianshu.com/p/ccb5f1de3246
C++const 关键字总结:https://www.runoob.com/w3cnote/cpp-const-keyword.html
【持续更新中...】