参考文献:constexpr介绍以及与const的区别-CSDN博客
定义
在 C++ 中,常量表达式是一种在编译期间就能计算出结果的表达式。
字面量常量:如整数字面量(1、2、3等)、字符字面量('a'、'b'等)、布尔字面量(true、false)和浮点字面量(3.14、2.718等)。例如,表达式3 + 4中的3和4就是整数字面量,整个表达式在编译时可以计算出结果为7。
const修饰的变量(满足一定条件):当一个变量被const修饰并且它的初始值是一个常量表达式时,这个变量也可以用于常量表达式。例如,const int a = 5;,这里a可以用于常量表达式,如a*2,因为a的值在编译时就已经确定为5,所以a*2在编译时可以计算出结果为10。不过,如果const变量是通过运行时才能确定的值初始化的,它就不是常量表达式。例如,int x; cin >> x; const int b=x;,这里的b不是常量表达式,因为它的值是在运行时通过用户输入确定的。
constexpr变量:这是 C++ 11 引入的一个关键字,是声明常量表达式的。constexpr变量在声明时必须初始化,并且初始化的值必须是一个常量表达式。constexpr变量本质上是为了更明确地定义常量表达式,并且它在编译时可以参与更复杂的计算,确保计算结果在编译时就能确定。
修饰常量:
#include <iostream>
using namespace std;
int main()
{
constexpr int num = 1 + 2 + 3;
int a[num] = {1,2,3,4,5,6};
cout<< a[1] << endl;//2
return 0;
}
修饰函数
- 整个函数的函数体中,除了可以包含 using 指令、typedef 语句以及 static_assert 断言外,只能包含一条 return 返回语句。
constexpr int display(int x) {
//可以添加 using 执行、typedef 语句以及 static_assert 断言
return 1 + 2 + x;
}
- 该函数必须有返回值,即函数的返回值类型不能是 void。
- 使用函数之前,必须先实现
- return 返回的表达式必须是常量表达式
用途
数组大小定义
在 C++ 中,定义数组时,数组的大小必须是一个常量表达式。例如,const int size = 10; int arr[size];,这里的size是一个常量,所以arr的定义是合法的。如果使用一个在运行时才能确定的值来定义数组大小,编译器会报错。这有助于在编译阶段检查数组大小是否合法,避免一些潜在的内存错误。
提高程序性能
由于常量表达式的值在编译时就已经确定,编译器可以对其进行优化。例如,对于一个包含常量表达式的循环条件,编译器可以在编译时就判断循环的执行次数,从而可能减少生成的机器指令数量。比如,constexpr int n = 100; for(int i = 0; i < n;++i),编译器知道循环会执行 100 次,它可以在编译时进行一些预先计算,而不是在每次运行程序的循环中都去判断循环条件。
模板参数
在模板编程中,常量表达式可以作为模板参数。例如,template struct Array{int data[N]; };,这里N是一个常量表达式模板参数。这样可以根据编译时确定的常量来定制模板类或模板函数的行为,使得代码更加灵活和高效。例如,可以定义一个大小为特定常量的数组模板类,在编译时就确定数组的大小,避免了运行时的动态内存分配开销等问题。
如何判断一个表达式是否是常量表达式?
从组成元素判断
字面量:如果表达式仅由字面量组成,那么它是常量表达式。字面量包括整数(如1、2、3)、浮点数(如3.14、2.718)、字符(如'a'、'b')、字符串(如"hello")和布尔值(true、false)。例如,3 + 4是常量表达式,因为3和4是整数字面量,通过加法运算得到的结果在编译时可以确定。
const变量(有限制):当一个变量被const修饰,并且它的初始值是常量表达式时,这个变量可以用于常量表达式。例如,const int a = 5;,a可以参与常量表达式,如a*2,因为a的值在编译时已知为5。但如果const变量的初始值是在运行时才能确定的,它就不是常量表达式。例如,int x; std::cin >> x; const int b = x;,b不是常量表达式,因为它的值依赖于运行时的用户输入。
constexpr变量和函数:被声明为constexpr的变量和函数在符合要求的情况下是常量表达式的组成部分。constexpr变量在声明时必须初始化,且初始值必须是编译时能确定的常量表达式。例如,constexpr int c = 3*4;是常量表达式。对于constexpr函数,其函数体应仅包含简单的操作,当以常量表达式为参数调用时,返回值在编译时可确定。例如,constexpr int square(int x) {return x*x;},constexpr int y = square(3);中y是常量表达式,因为square(3)在编译时可计算出为9。
枚举常量:枚举类型中的枚举常量是常量表达式。例如,enum Color {RED, GREEN, BLUE};,RED、GREEN和BLUE的值在编译时确定,可用于常量表达式。默认情况下,第一个枚举常量为0,后续的依次递增1,不过也可以手动指定枚举常量的值。
从使用场景判断
数组大小定义:在 C++ 中,数组大小必须是常量表达式。如果一个表达式可以用于定义数组大小,那么它是常量表达式。例如,constexpr int size = 10; int myArray[size];,这里size是常量表达式,因为它能用于定义数组大小。
模板参数(constexpr模板参数):在模板编程中,如果一个表达式可以作为constexpr模板参数,那么它是常量表达式。例如,template class MyArray {int data[N]; };,这里N要求是常量表达式,若某个表达式能够作为N的值,如constexpr int value = 5; MyArray myObj;,则value是常量表达式。
switch语句的case标签:在switch语句中,case标签必须是常量表达式。例如,constexpr int option = 2; switch(option) {case 1: std::cout
标签:const,常量,constexpr,int,C++,编译,表达式 From: https://blog.csdn.net/m0_73949707/article/details/143801251