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

[c/c++] const

const 和 #define 的区别 ?

const 和指针一块出现的时候,到底谁不能修改 ?

const 和 volatile 能同时修饰一个变量吗 ?

const 在 c++ 中的作用 ?

1 const 和 #define 的区别

const 和 #define 的相同点:

(1) 常数

const 和 #define 定义的对象,我们都可以当做一个常数来使用。


 

const 和 #define 的区别:

(1) 生命周期

#define 在编译预处理的时候会做字符串替换,替换之后宏就不存在了,也就是说宏的声明周期只存在于源码和预处理阶段。在目标文件中,程序运行的时候,宏是不存在的。

const 修饰的变量,在编译阶段会做语法检查,如果有显式修改,会报编译错误。const 常量在运行时也是实际存在的,存在于栈或者数据段中。

(2) 作用域

#define 定义的宏,只要包含了这个头文件,都可以使用这个宏;在源文件中,宏定义之后的代码也都可以访问这个宏;即使宏定义函数内部,那么这个宏定义后边的其它函数也是可以使用这个宏的。

const 修饰的局部变量只能在函数内访问,const 修饰的全局变量和普通全局变量的作用域是相同的。

(3) #define 修饰的宏可以 redifine

如下代码,在函数 test2() 内部对HOURS_PER_DAY 进行了重定义。重定义虽然是在函数内部,但是对后边的函数都是生效的。在 test2() 中重定义,在函数 test3() 中也是生效的。

#include <stdlib.h>
#include <stdio.h>
#include <string.h>#define HOURS_PER_DAY 24void test1() {printf("1, hours per day = %d\n", HOURS_PER_DAY);
}void test2() {#undef HOURS_PER_DAT#define HOURS_PER_DAY 20printf("2, hours per day = %d\n", HOURS_PER_DAY);
}void test3() {printf("3, hours per day = %d\n", HOURS_PER_DAY);
}int main() {test1();test2();test3();return 0;
}

在 c++ 编码规范中,推荐使用 const 常量,而不是 #define。

从上边的分析也可以看出来,#define 是可以重定义的,并且 #define 定义的宏没有作用域限制。这就可能给代码带来不安全性。

而对于 const 来说,局部变量的作用域只是函数内;全局 const 变量也不能重新修改。 const  的作用域限制更加严格,所以使用 const 安全性会更高。

2 const 和指针一块出现的时候,到底谁不能修改

const 修饰的是谁,那么谁就不能修改。

int a = 10;

int * const pa1 = &a; // const 修饰的是 int * 类型,是指针,所以 pa1 不能修改,*pa1 可以修改

const int *pa2 = &a; // const 修饰的是 int 类型,所以 pa2 可以修改,*pa2 不能修改

const int * const pa3 = &a; // pa3 和 *pa3 均不能修改

如下是代码和编译结果。

a 是 const 常量,所以不能修改。

p1 中 const 修饰的是 int 常量,所以 *p1 不能修改,p1 可以修改。

p2 中 const 修饰的是指针,所以 p2 不能修改,*p2 可以修改。

p3 const 修饰了指针和 int 值,所以 p3 不能修改,*p3 也不能修改。

3 const 和 volatile 能不能修饰同一个变量

可以。

这两个关键字,从字面意思上是有一些矛盾的。const 是说这个变量是常数,不能修改;volatile 又说这个变量是易变的。

但是两者可以修饰同一个变量,侧重点并不矛盾。const 是提醒编译器,这个变量是常数,不能在代码中显式修改,我们使用它的目的就是这样的,不让在代码中显式修改;volatile 说变量是易变的,告诉编译器,不要做访问优化,每次访问的时候都要到内存中去取值。

在嵌入式开发中,常常用到 volatile 来修饰寄存器变量,寄存器变量不允许软件显式修改,但是硬件可以修改。这个时候就可以使用 const 和 volatile 进行修饰。

4 const 在 c++ 中的作用

(1) 左值引用指向右值

如下代码 ra2 是左值引用,左值引用不能直接指向一个右值。

ra3 是一个 const 左值引用,可以指向一个右值。

从运行结果可以看出来,const 左值引用可以指向右值,右值也是保存在栈里的, ra3 的地址和 a 的地址挨着。

从运行结果可以看出来,const 引用 ra3,通过地址间接修改也是可以修改的。

#include <iostream>
#include <string>int main() {int a = 10;int &ra1 = a;// int &ra2 = 10; // error: cannot bind non-const lvalue reference of type ‘int&’ to an rvalue of type ‘int’const int &ra3 = 10;std::cout << "a addr = " << &a << ", ra3 addr = " << &ra3 <<std::endl;int *p = (int *)&ra3;std::cout << "ra3 = " << ra3 << std::endl;*p = 100;std::cout << "ra3 = " <<ra3 << std::endl;return 0;
}

(2) 修饰成员函数

用 const 修饰的成员函数,在函数中不能修改类的成员变量。

#include <iostream>
#include <string>class Test {
public:Test() {a = 10;std::cout << "Test()" << std::endl;}~Test() {std::cout << "~Test()" << std::endl;}void Do() const {a = 100;}void Do1(int data) {a = 100;data = 200;}int a;
};int main() {Test t;t.Do();return 0;
}

5 参考

linux 下 c 语言中的局部 const 常量可以修改

 [c 语言] 实例观察 c 语言中 volatile 的作用

相关文章:

[c/c++] const

const 和 #define 的区别 ? const 和指针一块出现的时候&#xff0c;到底谁不能修改 &#xff1f; const 和 volatile 能同时修饰一个变量吗 ? const 在 c 中的作用 ? 1 const 和 #define 的区别 const 和 #define 的相同点&#xff1a; (1) 常数 const 和 #define 定…...

生成商品条码

php生成商品条码&#xff0c;编码格式为&#xff1a;EAN13 下载第三方包&#xff1a;composer require codeitnowin/barcode 生成条码代码&#xff1a; $filename \Str::random(40) . .png;$barcode new BarcodeGenerator();$barcode->setText($barCode);$barcode->s…...

langchain学习笔记(十一)

关于langchain中的memory&#xff0c;即对话历史&#xff08;message history&#xff09; 1、 Add message history (memory) | &#x1f99c;️&#x1f517; Langchain RunnableWithMessageHistory&#xff0c;可用于任何的chain中添加对话历史&#xff0c;将以下之一作为…...

LabVIEW高温摩擦磨损测试系统

LabVIEW高温摩擦磨损测试系统 介绍了一个基于LabVIEW的高温摩擦磨损测试系统的软件开发项目。该系统实现高温条件下材料摩擦磨损特性的自动化测试&#xff0c;通过精确控制和数据采集&#xff0c;为材料性能研究提供重要数据支持。 项目背景 随着材料科学的发展&#xff0c;…...

基于YOLOv5的驾驶员疲劳驾驶行为​​​​​​​检测系统

&#x1f4a1;&#x1f4a1;&#x1f4a1;本文主要内容:详细介绍了疲劳驾驶行为检测整个过程&#xff0c;从数据集到训练模型到结果可视化分析。 博主简介 AI小怪兽&#xff0c;YOLO骨灰级玩家&#xff0c;1&#xff09;YOLOv5、v7、v8优化创新&#xff0c;轻松涨点和模型轻量…...

融合软硬件串流多媒体技术的远程控制方案

远程技术已经发展得有相当水平了&#xff0c;在远程办公&#xff0c;云游戏&#xff0c;云渲染等领域有相当多的应用场景&#xff0c;以向日葵&#xff0c;todesk rustdesk等优秀产品攻城略地&#xff0c;估值越来越高。占据了通用应用的方方面面。 但是细分市场&#xff0c;还…...

Spring中的数据校验---JSR303

介绍–什么是JSR303 JSR 303是Java中的一项规范&#xff0c;用于定义在Java应用程序中执行数据校验的元数据模型和API。JSR 303的官方名称是"Bean Validation"&#xff0c;它提供了一种在Java对象级别上执行验证的方式&#xff0c;通常用于确保输入数据的完整性和准…...

“揭秘网络握手与挥别:TCP三次握手和四次挥手全解析“

前言 在计算机网络中&#xff0c;TCP&#xff08;传输控制协议&#xff09;是一种重要的通信协议&#xff0c;用于在网络中的两台计算机之间建立可靠的连接并交换数据。TCP协议通过“三次握手”和“四次挥手”的过程来建立和终止连接&#xff0c;确保数据的准确传输。 一、三…...

Java开发工程师面试题(Spring)

一、Spring Bean的生命周期 生命周期可以分为以下几步&#xff1a; 通过Spring框架的beanFactory工厂利用反射机制创建bean对象。根据set方法或者有参构造方法给bean对象的属性进行依赖注入。判断当前bean对象是否实现相关aware接口&#xff0c;诸如beanNameAware、beanFactor…...

【C++】string类的基础操作

&#x1f497;个人主页&#x1f497; ⭐个人专栏——C学习⭐ &#x1f4ab;点击关注&#x1f929;一起学习C语言&#x1f4af;&#x1f4ab; 目录 导读 1. 基本概述 2. string类对象的常见构造 3. string类对象的容量操作 4. string类对象的访问及遍历操作 5. 迭代器 6.…...

Java项目:40 springboot月度员工绩效考核管理系统009

作者主页&#xff1a;源码空间codegym 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 本系统的功能分为管理员和员工两个角色 管理员的功能有&#xff1a; &#xff08;1&#xff09;个人中心管理功能&#xff0c;添加管理员账号…...

opengl 学习(三)-----着色器

着色器 分类demo效果解析教程 分类 OPengl C demo #include "glad/glad.h" #include "glfw3.h" #include <iostream> #include <cmath> #include <vector>#include <string> #include <fstream> #include <sstream>…...

电销平台架构的演变与升级

简介 信也科技电销平台承载了公司400多坐席的日常外呼任务&#xff0c;随着公司业务规模不断增长&#xff0c;业务复杂度不断提升&#xff0c;营销模式需要多样化&#xff0c;营销流程需要更加灵活。为了更好地赋能业务、提高客户转化率&#xff0c;电销平台不断升级优化&#…...

轻薄蓝牙工牌室内人员定位应用

在现代化企业管理的背景下&#xff0c;轻薄蓝牙工牌人员定位应用逐渐崭露头角&#xff0c;成为提升企业效率和安全性的重要工具。本文将从轻薄蓝牙工牌的定义、特点、应用场景以及未来发展趋势等方面&#xff0c;对其进行全面深入的探讨。 一、轻薄蓝牙工牌的定义与特点 轻薄…...

好物周刊#46:在线工具箱

https://github.com/cunyu1943 村雨遥的好物周刊&#xff0c;记录每周看到的有价值的信息&#xff0c;主要针对计算机领域&#xff0c;每周五发布。 一、项目 1. twelvet 一款基于 Spring Cloud Alibaba 的权限管理系统&#xff0c;集成市面上流行库&#xff0c;可以作用为快…...

20240306-1-大数据的几个面试题目

面试题目 1. 相同URL 题目: 给定a、b两个文件&#xff0c;各存放50亿个url&#xff0c;每个url各占64字节&#xff0c;内存限制是4G&#xff0c;让你找出a、b文件共同的url&#xff1f; 方案1&#xff1a;估计每个文件的大小为50G64320G&#xff0c;远远大于内存限制的4G。所以…...

Vue中如何处理用户权限?

在前端开发中&#xff0c;处理用户权限是非常重要的一个方面。Vue作为一种流行的前端框架&#xff0c;提供了很多便捷的方式来管理用户权限。本文将介绍一些Vue中处理用户权限的方法 1. 使用路由守卫 Vue Router提供了一个功能强大的功能&#xff0c;即导航守卫&#xff08;N…...

【STM32】HAL库 CubeMX教程---基本定时器 定时

目录 一、基本定时器的作用 二、常用型号的TIM时钟频率 三、CubeMX配置 四、编写执行代码 实验目标&#xff1a; 通过CUbeMXHAL&#xff0c;配置TIM6&#xff0c;1s中断一次&#xff0c;闪烁LED。 一、基本定时器的作用 基本定时器&#xff0c;主要用于实现定时和计数功能…...

2024年最新整理腾讯云学生服务器价格、续费和购买流程

2024年腾讯云学生服务器优惠活动「云校园」&#xff0c;学生服务器优惠价格&#xff1a;轻量应用服务器2核2G学生价30元3个月、58元6个月、112元一年&#xff0c;轻量应用服务器4核8G配置191.1元3个月、352.8元6个月、646.8元一年&#xff0c;CVM云服务器2核4G配置842.4元一年&…...

【QT】重载的信号槽/槽函数做lambda表达式

重载的信号槽 函数指针&#xff1a; int fun(int a,long b) int (*funp)(int, long) fun; 实现回调函数就需要函数指针 信号重载 派生类槽函数发送两个信号 派生类给父类发两个信号 void (SubWidget::*mysigsub)() &SubWidget::sigSub;connect(&subw,mysigsub,t…...

OpenClaw多设备同步:GLM-4.7-Flash配置共享方案

OpenClaw多设备同步&#xff1a;GLM-4.7-Flash配置共享方案 1. 为什么需要多设备同步配置&#xff1f; 去年冬天&#xff0c;我在办公室和家里两台MacBook上分别部署了OpenClaw对接GLM-4.7-Flash模型。很快发现一个头疼的问题&#xff1a;每次在办公室调试好的技能参数&#…...

彻底解决电脑噪音烦恼:FanControl风扇控制软件完全指南

彻底解决电脑噪音烦恼&#xff1a;FanControl风扇控制软件完全指南 【免费下载链接】FanControl.Releases This is the release repository for Fan Control, a highly customizable fan controlling software for Windows. 项目地址: https://gitcode.com/GitHub_Trending/f…...

从图像分割到GAN生成:转置卷积(Transpose Conv)的两种实战配置与调参心得

转置卷积实战指南&#xff1a;图像分割与GAN生成中的核心技巧 在计算机视觉领域&#xff0c;我们常常需要将低分辨率特征图恢复到原始尺寸——无论是为了像素级预测的图像分割任务&#xff0c;还是从潜在空间生成逼真图像的GAN模型。传统插值方法如双线性插值虽然简单&#xff…...

3分钟快速上手:免费高效的Elasticsearch可视化工具Elasticvue终极指南

3分钟快速上手&#xff1a;免费高效的Elasticsearch可视化工具Elasticvue终极指南 【免费下载链接】elasticvue Elasticsearch gui for the browser 项目地址: https://gitcode.com/gh_mirrors/el/elasticvue 你是否曾经为复杂的Elasticsearch集群管理而烦恼&#xff1f…...

从“高危论文”到“安心提交”:百考通双降技术,为真实思考护航

在一个人工智能可以生成万字论文的时代&#xff0c;最讽刺的现实不是机器冒充人类&#xff0c; 而是人类因写得太像“人写的论文”&#xff0c;被当作机器。 2026年&#xff0c;无数高校学子正陷入一场无声的困境&#xff1a; 你没用AI&#xff0c;却因逻辑清晰被标记&#xf…...

Llama-3.2V-11B-cot从零部署:Docker镜像运行与端口映射详解

Llama-3.2V-11B-cot从零部署&#xff1a;Docker镜像运行与端口映射详解 1. 项目概述 Llama-3.2V-11B-cot是基于Meta Llama-3.2V-11B-cot多模态大模型开发的高性能视觉推理工具。它针对双卡4090环境进行了深度优化&#xff0c;特别适合想要体验Llama多模态大模型但缺乏专业部署…...

VirtualBox虚拟机磁盘空间分配技巧:如何用动态分配40G空间玩转Debian 12

VirtualBox磁盘空间动态分配实战&#xff1a;以Debian 12为例的40GB高效配置指南 在虚拟化技术日益普及的今天&#xff0c;VirtualBox作为一款开源免费的虚拟化工具&#xff0c;凭借其跨平台特性和易用性&#xff0c;成为众多开发者和技术爱好者的首选。然而&#xff0c;许多用…...

智能变电站实战:如何用SCL配置文件搞定IED设备联调(附避坑案例)

智能变电站实战&#xff1a;SCL配置文件在IED设备联调中的关键作用与避坑指南 在智能变电站的工程实施中&#xff0c;设备联调环节往往成为项目进度的"拦路虎"。据统计&#xff0c;超过60%的现场调试时间消耗在IED设备间的通信配置问题上。SCL&#xff08;Substation…...

信息安全毕设容易的项目选题汇总

0 选题推荐 - 网络与信息安全篇 毕业设计是大家学习生涯的最重要的里程碑&#xff0c;它不仅是对四年所学知识的综合运用&#xff0c;更是展示个人技术能力和创新思维的重要过程。选择一个合适的毕业设计题目至关重要&#xff0c;它应该既能体现你的专业能力&#xff0c;又能满…...

从Python转C++必看:C++20的starts_with/ends_with和Python有何不同?5个易错点详解

从Python转C必看&#xff1a;C20的starts_with/ends_with和Python有何不同&#xff1f;5个易错点详解 当你在Python中熟练使用startswith()和endswith()多年后&#xff0c;突然切换到C20的starts_with和ends_with&#xff0c;可能会觉得"这不就是换个语法吗&#xff1f;&q…...