深入理解 C++ 中的 const 和 constexpr

在 C++ 中,constconstexpr 是两个关键字,它们分别用于定义常量,但它们的使用场景和作用有所不同。理解它们的区别和联系对于编写高效和可靠的代码至关重要。

1. const 关键字

1.1 基本概念

const 关键字用于声明常量。被声明为 const 的变量在其整个生命周期中不能被修改。

1.2 用法示例

const int x = 5;
x = 10; // 错误:x 是只读变量

1.3 特点

  • 编译期检查:编译器会在编译时检查 const 变量的赋值操作,确保它们不会被修改。
  • 可以用于指针和引用const 还可以用来修饰指针和引用,表示指向的值不能修改。
const int *ptr = &x; // 指向 const int 的指针
int const *ptr2 = &x; // 同上,另一种写法
int *const ptr3 = &x; // const 指针,指针本身不可变
const int &ref = x; // 指向 const int 的引用

1.4 函数中的 const

在函数中,const 可以修饰函数参数和成员函数。

  • 修饰参数:表示参数在函数内部不可修改。
  • 修饰成员函数:表示成员函数不会修改类的成员变量。
void func(const int a) {
    // a 不能被修改
}

class MyClass {
public:
    int getValue() const {
        return value; // 这个成员函数不会修改任何成员变量
    }
private:
    int value;
};

2. constexpr 关键字

2.1 基本概念

constexpr 关键字用于声明常量表达式。与 const 不同,constexpr 保证表达式在编译时求值。这意味着 constexpr 变量不仅是不可变的,而且其值在编译时就已经确定。

2.2 用法示例

constexpr int x = 5;
constexpr int y = x + 5; // 编译时求值

2.3 特点

  • 编译期常量constexpr 保证变量在编译时就能求值,从而可以用于数组大小、模板参数等需要编译时常量的地方。
  • 可以用于函数constexpr 函数的返回值在编译时求值,如果参数也是常量表达式。
constexpr int square(int x) {
    return x * x;
}

constexpr int y = square(5); // 编译时求值

2.4 与 const 的区别

  • 编译时求值constexpr 强制在编译时求值,而 const 只是在运行时不可修改。
  • 应用场景constexpr 更适用于需要在编译时确定值的场景,如模板参数、数组大小等,而 const 更适用于需要不可变但不要求编译时确定的场景。

3. constconstexpr 的联系

尽管 constconstexpr 有显著的区别,但它们也有一些联系:

  • 不可变性:两者都可以用于定义不可变的变量。
  • 互补性:在实际编程中,constconstexpr 常常互补使用。例如,可以使用 constexpr 定义编译时常量,然后用 const 修饰函数参数来保证参数不可修改。
constexpr int size = 10;
const int arr[size] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

4. 实际编程中的应用

4.1 数组大小

使用 constexpr 可以定义数组的大小,使得数组大小在编译时确定。

constexpr int size = 10;
int arr[size];

4.2 模板参数

模板参数需要编译时常量,constexpr 非常适合用于此场景。

template<int N>
struct MyArray {
    int data[N];
};

constexpr int size = 10;
MyArray<size> arr;

4.3 常量表达式函数

constexpr 函数可以在编译时求值,提高代码的执行效率。

constexpr int factorial(int n) {
    return n <= 1 ? 1 : n * factorial(n - 1);
}

constexpr int result = factorial(5); // 编译时计算

5. 结论

constconstexpr 是 C++ 中两个重要的关键字,它们分别用于定义常量,但各自有不同的应用场景和特点。const 用于声明在运行时不可修改的变量,而 constexpr 用于声明在编译时即可求值的常量表达式。理解和正确使用这两个关键字,可以使代码更安全、高效和易于维护。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/746487.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

深度之眼(二十六)——神经网络基础知识(一)

文章目录 一、前言二、神经网络与多层感知机2.1 人工神经元2.2 人工神经网络2.3 多层感知机2.4 激活函数 一、前言 看了下课程安排&#xff0c;自己还是没安排好&#xff0c;刚刚捋清了一下思路。 基础&#xff1a;python、数理 认识&#xff1a;神经网络基础、opencv基础、py…

加速科技Flash存储测试解决方案 全面保障数据存储可靠性

Flash存储芯片 现代电子设备的核心数据存储守护者 Flash存储芯片是一种关键的非易失性存储器&#xff0c;作为现代电子设备中不可或缺的核心组件&#xff0c;承载着数据的存取重任。这种小巧而强大的芯片&#xff0c;以其低功耗、可靠性、高速的读写能力和巨大的存储容量&…

C Tips: 举例说明在 Visual C++ 中忽略 C4996 编译警告的几种方法

C4996 编译警告非常常见&#xff0c;经常发生在程序调用了类似于strcpy这样的不够安全的函数时。例如以下代码在 Visual C 的默认工程设置中会引起 C4996 编译警告&#xff1a; void foo() {char filename[MAX_PATH];strcpy(filename, "D:\\Pub\\Test\\1.dat"); }编…

Springboot小型仪器公司生产管理系统-计算机毕业设计源码031853

摘 要 本论文主要论述了如何使用java语言开发一个Springboot小型仪器公司生产管理系统&#xff0c;本系统将严格按照软件开发流程进行各个阶段的工作&#xff0c;采用B/S架构&#xff0c;面向对象编程思想进行项目开发。在引言中&#xff0c;作者将论述小型仪器公司生产管理系统…

数据结构——带头双向循环链表(c语言实现)

目录 1.单链表和双向链表对比 2.双向链表实现 2.1 创建新节点 2.2 链表初始化 2.3 尾插 2.4 头插 2.5 尾删 2.6 头删 2.7 查找 2.8 指定位置后插入数据 2.9 删除指定节点 2.10 销毁链表 2.11 打印链表 前言&#xff1a; 我们在前几期详细地讲解了不带头单…

【C#】找不到属性集方法。get只读属性用了反射设置setValue肯定报错

欢迎来到《小5讲堂》 这是《C#》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解。 温馨提示&#xff1a;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不对之处望指正&#xff01; 背景 找不到属性集方法。get只读属性用了反射设置setValue肯定报错 报错…

OpenCv形态学(一)

目录 形态学转换 结构元素 腐蚀 膨胀 开运算 闭运算 形态学梯度 顶帽 黑帽 图像轮廓 查找轮廓 绘制轮廓 形态学转换 形态变换是一些基于图像形状的简单操作。通常在二值图像上执行。它需要两个输入&#xff0c;一个是我们的原始图像&#xff0c;第二个是决定操作性…

推荐系统(LLM去偏?) | (WSDM24)预训练推荐系统:因果去偏视角

::: 大家好&#xff01;今天我分享的文章是来自威斯康星大学麦迪逊分校和亚马逊AWS AI实验室的最新工作&#xff0c;文章所属领域是推荐系统和因果推理&#xff0c;作者针对跨域推荐中的偏差问题提出了一种基于因果去偏的预训练推荐系统框架PreRec。 ::: 原文&#xff1a;Pre-t…

2024年敏捷开发管理工具10大精选

国内外主流的十大敏捷开发管理系统&#xff1a;PingCode、Tapd、OpenProject、Jira、ClickUp、Monday.com、Wrike、Taiga、Tuleap、Redmine。 敏捷开发已成为软件开发领域的一种标准实践&#xff0c;有效的管理工具是其成功实施的关键。本文将探讨在2024年&#xff0c;哪些敏捷…

迁移学习——CycleGAN

CycleGAN 1.导入需要的包2.数据加载&#xff08;1&#xff09;to_img 函数&#xff08;2&#xff09;数据加载&#xff08;3&#xff09;图像转换 3.随机读取图像进行预处理&#xff08;1&#xff09;函数参数&#xff08;2&#xff09;数据路径&#xff08;3&#xff09;读取文…

基于redisson实现tomcat集群session共享

目录 1、环境 2、修改server.xml 3、修改context.xml 4、新增redisson配置文件 5、下载并复制2个Jar包到Tomcat Lib目录中 6、 安装redis 7、配置nginx负载均衡 8、配置测试页面 9、session共享测试验证 前言&#xff1a; 上篇中&#xff0c;Tomcat session复制及ses…

观测云 VS 开源自建

观测云是一款面向全技术栈的监控观测一体化产品方案&#xff0c;具备强大而丰富的功能&#xff0c;目标是帮助最终用户提升监控观测的能力&#xff0c;化繁为简&#xff0c;轻松的构建起完整的监控观测体系。同时能够帮助整个企业的开发技术团队从统一的观测能力上获得完整的收…

ONLYOFFICE 文档开发者版 8.1:API 更新

随着版本 8.1 新功能的发布&#xff0c;我们更新了编辑器、文档生成器和插件的 API&#xff0c;并添加了 Office API 板块。阅读下文了解详情。 ​ ONLYOFFICE 文档是什么 ONLYOFFICE 文档是一个功能强大的文档编辑器&#xff0c;支持处理文本文档、电子表格、演示文稿、可填写…

探索ChatGPT在程序员日常工作的多种应用

引言 在现代科技迅猛发展的今天&#xff0c;人工智能的应用已经深入到我们生活和工作的各个方面。作为程序员&#xff0c;我们时常面临大量繁杂的任务&#xff0c;从代码编写、错误调试到项目管理和团队协作&#xff0c;每一项都需要花费大量的时间和精力。近年来&#xff0c;…

算法与数据结构——时间复杂度详解与示例(C#,C++)

文章目录 1. 算法与数据结构概述2. 时间复杂度基本概念3. 时间复杂度分析方法4. 不同数据结构的时间复杂度示例5. 如何通过算法优化来提高时间复杂度6. C#中的时间复杂度示例7. 总结 算法与数据结构是计算机科学的核心&#xff0c;它们共同决定了程序的性能和效率。在实际开发中…

大模型产品的“命名经济学”:名字越简单,产品越火爆?

文 | 智能相对论 作者 | 陈泊丞 古人云&#xff1a;赐子千金&#xff0c;不如教子一艺&#xff1b;教子一艺&#xff0c;不如赐子一名。 命名之妙&#xff0c;玄之又玄。 早两年&#xff0c;大模型爆火&#xff0c;本土厂商在大模型产品命名上可谓下足了功夫&#xff0c;引…

C#+uni-app医院HIS预约挂号系统源码 看病挂号快人一步

​​​​​​​ 提到去大型医院机构就诊时&#xff0c;许多人都感到恐惧。有些人一旦走进医院的门诊大厅&#xff0c;就感到迷茫&#xff0c;既无法理解导医台医生的建议&#xff0c;也找不到应该去哪个科室进行检查。实际上&#xff0c;就医也是一门学问&#xff0c;如何优化…

【CS.DS】数据结构 —— 图:深入了解三种表示方法之邻接表(Adjacency List)

文章目录 1 概念2 无向图的邻接表2.1 示例2.2 Mermaid 图示例2.3 C实现2.3.1 简单实现2.3.2 优化封装 2.4 总结 3 有向图的邻接表3.1 示例3.2 C实现3.3 总结 4 邻接图的遍历5 拓展补充References 数据结构 1 概念 优点&#xff1a;空间效率高&#xff0c;适合稀疏图。动态性强…

Win10,Win11电脑重装系统怎么操作,简单一步搞定【保姆级教程】

电脑重装系统怎么操作&#xff1f;电脑使用时间长了&#xff0c;就会出现系统崩溃、病毒感染或者是系统文件损坏等问题。这个时候我们就可以对电脑进行系统重装&#xff0c;也就是恢复电脑出厂设置。现在市面上有很多系统重装工具可以帮助我们解决难题&#xff0c;如果您是电脑…

自定义 Django 管理界面中的多对多内联模型

1. 问题背景 在 Django 管理界面中&#xff0c;用户可以使用内联模型来管理一对多的关系。但是&#xff0c;当一对多关系是多对多时&#xff0c;Django 提供的默认内联模型可能并不适合。例如&#xff0c;如果存在一个产品模型和一个发票模型&#xff0c;并且产品和发票之间是…