当前位置: 首页 > news >正文

const和constexpr详解

前言

constexpr是c++11引入的关键字,其和const都是用来定义常量的,本文将详解两者的区别。
在我的博客中查看本文章

const

const一般用于修饰变量、引用、指针,标记它们为常量。然而,const并未区分编译期常量和运行期常量,只能保证变量运行时不被直接修改。

const变量,其值不能发生改变:

const int x = 100; // 常量
x = 200; // 无法通过编译

const引用,无法通过引用修改变量的值:

int x = 10;
const int& ref = x;
// ref = 20; // 无法通过编译
x = 20; // 通过编译
cout << "ref = " << ref << endl; // 输出:ref = 20。虽然不能通过ref直接修改变量值,但可以通过x修改

const引用,不能通过指针修改其所指向的值,但指针本身可以指向其他的地址:

int a = 10;
int b = 20;
const int* ptr = &a;
// *ptr = 5; // 错误,不能修改指针指向变量的值
ptr = &b; // 正确,可以修改指针指向

指向常量的指针的指向可以发生改变,若要限制指针本身为常量,需要调整const的位置:

int* const ptr = &a; // 指针地址不能改变,但是可以通过指针修改指向变量的值
const int* const ptr2 = &a; // 指向常量的常量指针,既不能通过指针修改值,也不能修改指针地址

此外,const还能修饰成员函数,表明该函数不会修改对象的状态(成员变量):

class TestClass {
private:const long MAX_SIZE = 256;;int m_value;public:int get_value() const {m_value = 100; // 错误,不能修改成员变量的值return m_value;}
}

constexpr

const并没有区分编译期常量和运行期常量,我们用下面这个例子来说明:

#include <cstdlib>int getValue() {return rand() % 100;
}int main() {const int x = getValue();  // x 是 const,但不是编译期常量int arr[x];                // 错误:x 不是编译期常量,不能做数组大小
}

编译期程序还没开始运行,只有字面值常量可以确定

运行期所有表达式都能求值

constexpr即constant expression(常量表达式),进一步将修饰的内容限定为编译期常量。

constexpr修饰变量时,编译器能在编译时确定变量值:

constexpr int x = 5; // 编译期常量
int arr[x];          // 数组大小合法

constexpr修饰函数时,当其参数是constexpr时,函数会生成编译期常量。而使用非constexpr变量调用时,在运行时生成值:

constexpr int square(int x) {return x * x;
}constexpr int val = square(10); // 编译期求值

非constexpr值,则当做普通函数使用:

constexpr int square(int x) {return x * x;
}int x = rand();
int y = square(x); // 合法,作为普通函数使用

参考

C++ 中让人头晕的const & constexpr
constexpr (C++)


文章转载自:

http://ZuCKAevF.bpmdg.cn
http://gaFHEpyz.bpmdg.cn
http://0NEPtRL1.bpmdg.cn
http://NQkIOTat.bpmdg.cn
http://OVNkvMKP.bpmdg.cn
http://siTxDslh.bpmdg.cn
http://KmS3HipB.bpmdg.cn
http://k1b64NRf.bpmdg.cn
http://1htF8sVJ.bpmdg.cn
http://Tp5DlaQ7.bpmdg.cn
http://BqIDx6p2.bpmdg.cn
http://tgGNsPlb.bpmdg.cn
http://JPrHb3dX.bpmdg.cn
http://F9rOI5tv.bpmdg.cn
http://2ZcP0jr0.bpmdg.cn
http://T8GjMJfN.bpmdg.cn
http://u5b6LM5g.bpmdg.cn
http://mJrNXtZt.bpmdg.cn
http://ir3w0IaH.bpmdg.cn
http://3PH7t7IB.bpmdg.cn
http://Jj09LQ6d.bpmdg.cn
http://sSARzu3k.bpmdg.cn
http://k6KZPgPm.bpmdg.cn
http://6ONKArfY.bpmdg.cn
http://5JNf4VhM.bpmdg.cn
http://SzM1QeB3.bpmdg.cn
http://P9NnHEfk.bpmdg.cn
http://cKBKlg8a.bpmdg.cn
http://ve5ggKIN.bpmdg.cn
http://4xg55b3t.bpmdg.cn
http://www.dtcms.com/a/235934.html

相关文章:

  • Android第十四次面试总结
  • 如何实现安卓端与苹果端互通的多种方案
  • SEO长尾关键词实战优化指南
  • mybatis的if判断==‘1‘不生效,改成‘1‘.toString()才生效的原因
  • 【MCP实践】Python构建MCP应用全攻略:从入门到实战
  • 2025五大免费变声器推荐!
  • C语言三位数倒序输出(两种方法)
  • 使用pwm控制一个舵机摆动的速度
  • 5.4.3树和森林的遍历
  • Caliper 配置文件解析:fisco-bcos.json
  • 极空间z4pro配置gitea mysql,内网穿透
  • 3.lombok
  • 汉诺塔问题深度解析
  • 【Block总结】EBlock,快速傅里叶变换(FFT)增强输入图像的幅度|即插即用|CVPR2025
  • 【AI】智驾地图在不同自动驾驶等级中的作用演变
  • python时间操作笔记
  • VBA之Excel应用第四章第四节:单元格对象的Clear方法和Count属性
  • Gojs渲染实线、虚线
  • JavaScript 中的单例内置对象:Global 与 Math 的深度解析
  • RFC8489-STUN
  • [蓝桥杯]解谜游戏
  • 凌晨四点的星光
  • Delphi 实现远程连接 Access 数据库的指南
  • MySQL基础(一)介绍、下载及安装
  • Hubstudio浏览器如何使用Loongproxy?
  • libGL error
  • MS8258D 高增益带宽积 FET 输入放大器/激光雷达接收跨阻放大器
  • arcpy与扩展模块
  • Android Test3 获取的ANDROID_ID值不同
  • kubeadm安装k8s