1、常量表达式是什么
在编译时就能确定其值的表达式。换句话说,常量表达式的值在编译过程中就已经是已知且不会改变的。常量表达式是由 数据类型 和 初始值 共同决定的。(注意区分const 和 常量表达式)
常量表达式的特点:
- 值在编译时已知:常量表达式的值在编译阶段就能确定,而不是在运行时。
- 不会改变:常量表达式的值一旦确定,就不会再改变。
- 不包含函数调用:除了几个特定的内置函数(如sizeof)外,常量表达式通常-不包含函数调用,因为函数调用可能会在运行时产生不同的结果。
- 通常用于初始化常量:常量表达式常用于初始化常量,如数组的大小、枚举值、constexpr变量等。
以下为几个例子:
const int a1 = 10; //a1为常量表达式
const int a2 = a1 + 10; //a2为常量表达式
int a3 = 10; //a3不为常量表达式,非const int类型
const int a4 = fun(); //需要运行时确定值,非编译时期
2、constexpr
constexpr是C++中的一个关键字,用于指定常量表达式。
constexpr函数是能用于常量表达式的函数,它们的返回值类型及所有形参的类型都必须是字面值类型,并且函数体中必须有且只有一条return语句。constexpr函数被隐式地指定为内联函数,以便在编译过程中随时展开。
int fun()
{return 10;
}int main()
{constexpr int a = 10;constexpr int b = a + 10;constexpr int c = fun(); //error,fun函数必须是constexpr类型return 0;
}
constexpr int fun()
{}int main()
{constexpr int a = 10;constexpr int b = a + 10;constexpr int c = fun(); //error,fun函数必须有返回值return 0;
}
3、constexpr和指针
在C++中,constexpr
用于指示一个值或表达式是常量表达式,它的值在编译时是已知的且不会改变。
以下是关于constexpr
和指针的一些要点:
-
指向常量的指针:
一个指针可以是constexpr
,如果它指向的对象是常量,并且该指针在初始化后不会改变。但是,这并不保证所指向的对象的内容也是常量(只是指针本身是常量)。constexpr int* ptr = &a; // 指向常量的指针 // 注意:a 必须是一个在编译时已知地址的常量
-
指向字面量的指针:
指向字符串字面量或其他字面量的指针也可以是constexpr
,因为这些字面量的地址在编译时是已知的。constexpr char* str = "Hello, constexpr!"; // 指向字符串字面量的指针
-
指针的初始化:
constexpr
指针必须在声明时初始化,并且之后不能修改。constexpr int value = 42; constexpr int* ptr = &value; // 正确:在声明时初始化 ptr = &anotherValue; // 错误:不能修改constexpr指针
-
指针运算:
由于constexpr
指针指向的值在编译时是已知的,因此你不能对它们进行指针运算(如递增或递减),除非这些运算的结果在编译时也是已知的。 -
指向数组的指针:
你可以有一个constexpr
指针指向数组的首元素,但这并不意味着整个数组都是constexpr
。只有数组的内容在编译时已知,并且数组本身被声明为constexpr
时,这样的数组才是constexpr
数组。 -
指向非常量数据的
constexpr
指针:
虽然技术上可以有一个constexpr
指针指向非常量数据(即不是const
的数据),但这样做通常没有太多意义,因为constexpr
的主要目的是表示编译时常量。 -
constexpr
函数和指针:
在constexpr
函数中,你可以返回指向常量数据的指针,但返回的指针必须指向在编译时已知地址的对象。constexpr int* getPointer() {static int value = 42; // 静态局部变量具有固定的地址return &value; }