C++const限定符与constexpr限定符

const限定符

const基本介绍

当我们有一个变量,我们为它赋了一个值后,就不用再去修改它,也不希望它被其他方式修改,我们就可以用const限定符对该变量进行修饰,使它变成一个常量,不能随意修改。

int num1=20;
const int num2=30;
num1=22;	//对,因为num1是一个变量,它的值可以随意修改
num2=33;	//错,num2是const int类型,是一个常量,不能随意修改

在用const修饰一个对象时,该对象一定要初始化,当然,初始化的值不一定要是常量,也可以是非常量。并且,const对象也可以作为初值去赋另外一个对象。

int a=10;
const int num5;	//错,一定要初始化
const int num4=10;
const int num3=a;	//对,a的值被拷贝给了num3
int b=num3;	//对,num3的值被拷贝给了b

const与引用

我们可以把引用绑定到const对象上,就像绑定到其他对象上一样,我们称为对常量的引用。但与普通引用不同的是,他不能用来去修改所绑定得对象。
C++引用的前提是:该引用的类型与要 绑定对象的类型必须一致。
但在《C++ Primer》中提到在这里有两种特殊情况。
1、在初始化常量中引用时允许用任意表达式作物初始值,只要该表达式的结果能转化成引用的类型即可。尤其,允许为一个常量引用绑定一个非常量的对象、字面值,甚至一个表达式。
2、目前还没看到,以后看到了再回来补充。
不过,对于第一点,我个人是这样理解的:
等号右边的可能性要包含等号左边的可能性
这句话在我目前遇到的所有const中都适用,不止const 与引用中。
怎么理解呢,举个简单的例子

const int a=10;
int b=20;

const int &num1=a;	//对
const int &num1=b; //对

int &num2=a;	//错,num2是int 类型的引用,而a是const int类型,两者类型不一致,不能引用。
int &num2=b;	//对

double val=3.14;
const int &num3=val; //对

对于上述代码中:
1、const int &num1=b;
等号左边:const int类型的引用,const int是常量,只有不变一种可能性。
等号右边:int类型的变量,既然是变量,那么它就可以变或者不变,即两种可能性(当然深挖理解,肯定不止两种,如隐式转换成其他类型也是,这里方便理解,就说两种)。所以右边的可能性包含了左边的,所以正确。
2、 int &num2=a;
等号左边:int类型的引用,有变或不变两种。
等号右边:a是const int类型的变量,只有不变一种显然,右边是不包含左边的。所以是错的。
3、const int &num3=val;
等号左边:const int 类型的引用,只有int类型的不变。
等号右边:val是double类型,但是可以隐式转换为int类型,所有他有double类型的变或不变、int类型的变或不变四种可能性。实际的式子可能是:

const int temp=val;
const int num3=temp;

显然是包含了左边的,所以是对的。
注:以上观点,只是个人为了方便理解带入的概念,实际在C++ 中应该是不存在的。请谨慎采用!

const与指针

判断是否合法和上面说的基本一致。
所以我这里只给大家带来,怎么去读,去理解这个 const和指针的两种形式。

int val=10;
const int *p1=&val;

int *const p2=&val;

先说明:理解所有与指针相关的东西,他的读法,都从定义的指针开始,从右往左读。比如const int *p1=&val;就是从p1开始,往右读。
记住上述观点,我们现在开始去理解上面的代码。
1、const int p1=&val;
首先,临近p1左边最近的"*"号,所以p1先是一个指针;
接着在往左看,int,说明p1是一个指向整型的指针;
在最左边是const,说明p1是一个指向整型常量的指针,即
指针常量*
2、int const p2=&val;
同理,p2开始从右往左,左边最近的是一个const,说明p2一个常量,但目前还不知道类型。
接着 ,在左边是一个”*“号,说明p2是一个常量指针。
最左边,是int,说明p2是一个指向整型的常量指针,即
指针的指向不能改变,但是所指的对象的值是可以改变的。*

对于,上诉两种情况,如果你把const在两个位置都加上的话,也是同样的理解。只要记住无论是const还是"*"号,本质都是一个修饰符,然后理解顺序,从右往左,依次把修饰符给定义的变量加上就行。

constexpr修饰符

常量表达式

在了解constexpr前,我们的先了解一个概念:常量表达式
什么是常量表达式?
常量表达式是值不会改变并且在编译过程中就会的到结果的表达式。
两个要点:
1、值不会改变

int val=10;
const int test1=val;

在const中,可以通过一个变量给const 赋值,并且还可以通过修改该变量的值,来达到修改该const变量的目的。在这里面,对于val来说,他是一个变量,不是常量,而”10“才是一个常量。(记住这点,下面会用)
2、编译过程中就会的到结果
要在编译过程中就得出结果,不能等到运行的时候,才得到结果。
像cin.get()这里要在运行时输入才能得到结果的,显然不是。

constexpr基本介绍

声明为constexpr的变量,会由编译器来验证该变量的值是否是一个常量表达式,所以该变量一定是一个常量,而且必须由常量表达式来初始化:

int val=10;
constexpr int num1=20;	//对,20是常量表达式
constexpr int num2=val;	//错,val不是常量表达式
constexpr int num3=num1+11;	//对,num1本身就是一个常量,所以num2+11是一个常量表达式
constexpr char num4=cin.get();	//错,不能再运行时才得到结果

指针与constexpr

与const和指针放在定义中的相对位置不同,就会有不同的意思不同,constexpr只能放在类型符号的前面(即左边),不能放在右边。而且如果再constexpr声明中,定义了一个指针,那么限定符constexpr只对指针有效,与指针所指的对象无关。

const int *p1=nullptr;	//p1是一个指向整型常量的指针
int * const p2=nullptr;	//p2是一个指向整数的常量指针
constexpr int *p3=nullptr;	//p3也是一个指向整数的常量指针

constexpr指针与其他的常量指针类似, 既可以指向常量,也可以指向一个非常量。

int val=10;
constexpr int *p4=&val;

总结

以上就是我个人参考了《C++ Primer》之后,对于const和constexpr的浅薄理解,上面还有一些不是很清楚的地方,等后面学会了再回来补充。如果有说的不对的地方,欢迎各位大佬再评论区给予纠正或补充,万分感谢!

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值