目录

​1,字面值和只读变量​

​2,const​

​3,constexpr​


1,字面值和只读变量

在C++中,常量包括字面值和只读变量

int a=12345;
const int b=123;

这里,12345是字面值,a是变量,b是只读变量。

12345是常量,b是常量,a不是常量。

在C中,常量只包括字面值,只读变量不是常量。

上述代码在C语言的解读是,12345是常量,b不是常量。


C和C++中,定义数组的大小都只能用常量

所以C++有2种定义数组的方法:

const int b=123;
int c[123];
int d[b];

这2中写法都是正确的。

但是在C语言中,上述d数组如果是全局变量就是非法的,如果是局部变量那就是可变长数组

2,const

关键字const叫做限定符,因为它限定了声明的含义。

C和C++的区别(1)常量和只读变量、数组定义_字面值

const变量是区分编译期常量和运行期常量

const int b=123;
int d[b];

这是的b编译期常量

int f(int a)
{
const int b=a;
int d[b];
cout<<sizeof(d)/sizeof(int);
return 0;
}

这里的b是运行期常量,它的值在编译期是未知的,

所以数组d的定义理论上是非法的,但是我在本地实测,以及力扣实测,都是可以的,应该是编译器做了优化,把这个按照C语言的可变长数组的逻辑去编译了。

于是我在网上找到了另外一种代码,用array检测一个变量是不是常量:

#include<iostream>
#include <array>
using namespace std;

int main()
{
int a;
const int b=a;
const int c=10;
//array<int,b>arr;
array<int,c>arr2;
return 0;
}

用运行期常量给array对象分配空间是不行的,必须用编译期常量才行。

总之,const变量是区分编译期常量和运行期常量的,,而字面值当然都是编译期常量。

3,constexpr

先看如下代码:

#include<iostream>
#include <array>
using namespace std;

const int f(int a)
{
return a*a;
}

int main()
{
// array<int,f(5)>arr;
return 0;
}

编译不过是因为,f(5)是运行期常量,而array需要的是编译期常量

把const换成constexpr之后:

#include<iostream>
#include <array>
using namespace std;

constexpr int f(int a)
{
return a*a;
}

int main()
{
array<int,f(5)>arr; //5是字面值
int a=5;
//array<int,f(a)>arr2; //a是变量
const int b=5;
array<int,f(b)>arr3; //b是编译期常量
const int c=a;
//array<int,f(c)>arr4; //c是运行期常量
return 0;
}

这样,5和b是编译期常量,所以f(5)和f(b)是编译期常量,而f(a)和f(c)都不是编译期常量,所以不能用来分配array对象。

总之,constexpr的作用是,在能返回编译期常量的条件下,就返回编译期常量。