怎么样通过做网站赚钱,中国建设工程招标网官网,seo站长工具平台,世界局势最新消息C const、constexpr与consteval作用与区别 在C 常量表达式和编译时优化中#xff0c;我们已经提到了常量、编译时常量与运行时常量的概念。为了加深理解#xff0c;我们再重新明晰一下这三者的概念。 常量#xff1a;初始化之后便不可修改的量。在c中使用const修饰的“变量”…C const、constexpr与consteval作用与区别 在C 常量表达式和编译时优化中我们已经提到了常量、编译时常量与运行时常量的概念。为了加深理解我们再重新明晰一下这三者的概念。 常量初始化之后便不可修改的量。在c中使用const修饰的“变量”称为常量。const修饰的常量可以是编译时常量也可以是运行时常量。现代编译器将自行推理决断。 #includeiostream
int main(){const int x{1};std::cout x std::endl;//可以读取x 5 //error编译错误常量不可修改
}编译时常量在编译时编译器将常量的值计算出来不必等到每次运行时计算。 #includeiostream
int main(){const int x{1 8};std::cout x std::endl;
}就像上面的代码若不优化则每次运行编译后的程序时都需要计算 1 8 18 18,如果程序执行一百万次则 1 8 18 18将被计算一百万次。这完全是没有必要的。 优化后的结果类似以下代码 #includeiostream
int main(){const int x{9};std::cout x std::endl;
}运行时常量程序运行时才确定下来的常量。 #includeiostream
int main(){int a 9;const int x{a}; //由于a是一个变量所以x只能在运行到此处的时候才能确定值。std::cout x std::endl;
}constexpr
尽管现代编译器已经可以自主判断是否应该编译时优化但是由于某些表达式十分复杂仅仅依赖于编译器是十分困难的。于是c提供了constexpr关键字它告诉编译器其修饰的常量是编译时常量可以在编译时优化。
注意 constexpr表示该对象可以在常量表达式中使用。初始值设定项的值在编译时必须已知。constexpr对象可以在运行时或编译时进行计算。constexpr与std::string、std::vector和其他使用动态内存分配的类型不完全兼容。
#include iostreamdouble nonconstexpr_ex(double radius)
{constexpr double pi { 3.14159265359 };return 2.0 * pi * radius;
}
constexpr double constexpr_ex(double radius)
{constexpr double pi { 3.14159265359 };return 2.0 * pi * radius;
}
int main()
{constexpr double circumference { nonconstexpr_ex(3.0) }; // 编译错误constexpr double circumference { constexpr_ex(3.0) }; // 正确std::cout Our circle has circumference circumference \n;return 0;
}注
constexpr 函数也可以在运行时进行计算。所以在非必要时编译器可自行选择函数是否在编译时计算。constexpr 函数是隐式内联的, 编译器必须能够看到constexpr或 consteval函数的完整定义而不仅仅是前向声明。
consteval
consteval是c20引入的关键字。用于指示函数必须在编译时计算否则将导致编译错误。此类函数称为即时函数immediate functions。