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

深入了解C++中const的用法

文章目录

    • 一、C++中的const如何理解?
    • 二、C++中的const与C语言中的const有何区别?
    • 三、const与指针、引用的结合使用

一、C++中的const如何理解?

在C++中,const是一个关键字,用来表示常量性,意在告诉编译器某些变量或对象的值是不可修改的,从而提高代码的安全性和可读性。

二、C++中的const与C语言中的const有何区别?

1. 语义层面的不同

在C语言中,const更多地是一个承诺,它表示变量在当前作用域中不能被修改,但这种约束不是绝对的,可以通过特定的方式绕过,例如强制类型转换。
在C++中,const语义更加严格和完善。它不仅约束变量,还能作用于成员函数、引用、指针等,且配合C++的类型系统,实现了更强的编译时检查。

2. const与引用

在C语言中没有引用的概念,因此const无法结合引用使用。
C++支持常量引用,用来避免拷贝,提高效率,同时保护原始数据不被修改。

void func(const int& ref) {// ref 是只读的,不能修改原始值
}

这种用法在C++中非常常见,特别是在传递大型对象时。

3. 修饰函数

C语言没有成员函数的概念,因此const无法作用于函数级别。
C++允许const修饰成员函数,表示该函数不会修改对象的状态。这种语义在面向对象编程中非常重要。

class MyClass {
public:void display() const { /* 不会修改成员变量 */ }
};

4.绕过const的方式
C语言可以通过强制类型转换((int*))来绕过const的限制。在C语言中const修饰的变量,可以不用初始化,它不叫常量,而是叫常变量。

const int a = 20;
int *p = (int*)&a;
*p = 30;
printf("%d %d %d\n", a, *p, *(&a));

输出结果:30 30 30

虽然C++也支持强制类型转换,但C++提供了更安全的const_cast,明确表示是移除const限定符。

const int a = 10;
int* p = const_cast<int*>(&a);
*p = 20; // 合法,但可能导致未定义行为

5.编译方式不同

在C语言中const就是被当作一个变量来编译生成指令的。
在C++中,所有出现const常量名字的地方,在编译时都被常量的初始化值替换了。且不能作为左值。

在C++中const用字面常量去初始化,如:

int main() {const int a = 20;//a是使用立即数进行的初始化,所以a为常量int array[a] = {};int* p = (int*)&a;*p = 30;std::cout << a << "," << *p << std::endl;return 0;
}

输出结果:20,30

在C++中const用变量去初始化,如:

int main() {int b = 20;const int a = b;//a的初始值不是立即数,是一个变量,所以a此时为常变量//int array[a] = {}; //无法使用变量初始化数组int* p = (int*)&a;*p = 30;std::cout << a << "," << *p << std::endl;return 0;
}

输出结果:30,30

三、const与指针、引用的结合使用

const修饰的变量常出现的错误是:

常量不能作为左值(不能直接修改常量的值)。
不能把常量的地址泄露给一个普通指针或者普通的引用变量(不能间接修改常量的值)。

int main() {const int a = 10;int b = 20;a = b; //错误:常量a不能再作为左值,表达式必须是可修改的左值int* p = &a; //错误: 不能将const int* 转换为int*,这样就会间接修改a的值return 0;
}

1.const和一级指针的结合
注意:const修饰的是离它最近的类型

const int *p:const离int最近,所以修饰的是int类型,而const修饰的表达式是*p,这个时候就不能再修改*p的值,即指针的指向不能再做修改(指针的指向是常量),但是指针的本身是可以被修改的,比如p = &b。换句话说就是p可以指向不同的int类型的内存,但是不能通过指针间接修改指向的内存的值。
int const *p:const离int最近,修饰的是int类型,所以const修饰的表达式是*p,作用同上。
int *const p:const离int*最近,修饰的是int*类型,所以const修饰的是p本身。即这个指针的本身是常量,所以一旦p初始化指向某块内存,那么就不能再更改它的指向。但是可以通过指针解引用修改指向的内存的值。
const int *const p:其作用是const int *p与int *const p的结合。

int main() {int* q1 = nullptr;int* const q2 = nullptr;std::cout << typeid(q1).name() << std::endl;std::cout << typeid(q2).name() << std::endl;// const如果右边没有指针*的话,const是不参与类型的// 比如说下面的const p3,表明p3是一个常量,即指针的指向不能再做改变int a = 10;int* p1 = &a;const int* p2 = &a; // const int* 转换为 int*int* const p3 = &a; // int* 转换为 int*int* p4 = p3; //int* 转换为 int*return 0;
}

2.const和二级指针的结合

const和二级指针结合的几种方式

const int**q:const修饰的类型是int,而它修饰的表达式是**q,所以**q不能被赋值,但是*q可以被赋值,q本身可以被赋值。
int *const *q:const修饰的类型是int *,而它修饰的表达式是const *q,所以*q不能被赋值,但是**q可以被赋值,q本身也可以被赋值。
int ** const q:const修饰的类型是int**,而它修饰的表达式是q,所以q本身不能被赋值,但是*q和**q可以被赋值。

3.总结const和指针的类型转换公式

int* 转换为 const int* 是不可行的。
const int* 转换为 int* 是可行的。
int ** 转换为 const int** 是不可行的。
const int** 转换为 int **是不可行的。
int** 转换为int* const*是错误的。
int* const*转换为int**是可行的

4.const和一级指针,引用的结合使用

//写一句代码:在内存的0x0018ff44处写一个4字节的10
int *p = (int*)0x0018ff44;
int *const &p1 = (int*)0x0018ff44; //(非常量引用的初始值必须为左值)0x0018ff44已经为常量了,如果使用引用,需要使用const修饰
int *&&p2 = (int*)0x0018ff44; //也可以使用右值引用(什么是右值:没内存,没名字,即字面常量)

相关文章:

深入了解C++中const的用法

文章目录 一、C中的const如何理解&#xff1f;二、C中的const与C语言中的const有何区别&#xff1f;三、const与指针、引用的结合使用 一、C中的const如何理解&#xff1f; 在C中&#xff0c;const是一个关键字&#xff0c;用来表示常量性&#xff0c;意在告诉编译器某些变量或…...

【Linux金典面试题(上)】41道Linux金典面试问题+详细解答,包含基本操作、系统维护、网络配置、脚本编程等问题。

大家好&#xff0c;我是摇光~&#xff0c;用大白话讲解所有你难懂的知识点 之前写了一篇关于 python 的面试题&#xff0c;感觉大家都很需要&#xff0c;所以打算出一个面试专栏。 【数据分析岗】Python金典面试题 这个专栏主要针对面试大数据岗位、数据分析岗位、数据运维等…...

利用Python实现多元回归预测汽车价格

引言: AI技术的热门使得大家对机器学习有了更多的关注,作为与AI技术息息相关的一门课程,从头了解基础的机器学习算法就显得十分有必要,如:梯度下降,线性回归等。 正文: 本文将讲解线性回归中多元回回归的案例 机器学习大致可以分为监督学习,非监督学习、半监督学习还…...

抓包软件fiddler和wireshark使用手册

fiddler官方文档 Fiddler 抓包教程1 Fiddler 抓包教程2 wireshark抓包学习 2添加链接描述 ip 过滤 ip.src_host ip.dst_host ip.addr mac 过滤 eth.src eth.dst eth.addr 端口过滤 tcp.port tcp.srcport tcp.dstport 协议类型过滤 arp dhcp 规则组合 and or...

初识三大 Observer

文章目录 ResizeObserver、MutationObserver和IntersectionObserver用MutationObserver实现图片懒加载MutationObserver 兼容性问题IntersectionObserver 应用MutationObserver和IntersectionObserver的区别IntersectionObserver 实例示例一&#xff1a;图片懒加载示例二&#…...

Eclipse MAT(Memory Analyzer Tool) 使用手册

参考&#xff1a;JAVA内存泄露使用MAT(Memory Analyzer Tool)快速定位代码 Eclipse MAT 1.15.0提示JDK版本最低需要使用17版本的&#xff0c;如果不想安装可以下载ZIP包&#xff0c;或者使用较低版本的MAT。 为了避免下载的17版本JDK和本地环境干扰&#xff0c;可以直接在MAT配…...

TongWe7.0-东方通TongWeb控制台无法访问 排查

**问题描述&#xff1a;**无法访问TongWeb的控制台 逐项排查&#xff1a; 1、控制台访问地址是否正确&#xff1a;http://IP:9060/console #IP是服务器的实际IP地址 2、确认TongWeb进程是否存在&#xff0c;执行命令&#xff1a;ps -ef|grep tongweb 3、确认TongWeb服务启动…...

Ariba Procurement: Administration_Master data

采购主数据集成Procurement Master Data Integration 注意&#xff1a;并非所有元素都是必需的&#xff0c;数据元素的名称可能根据ERP的不同&#xff0c;有所不同。 Types of Master Data Accounting 在SAP Ariba中的各种会计元素字段中&#xff0c;填充有效值选择列表。建…...

爬虫学习案例4

爬取猪八戒网站数据&#xff1a;2024-12-12 使用xpath解析元素&#xff0c;安装依赖库 pip install lxml使用selenium步骤我的上篇博客有提到&#xff0c;这里就不重复了 selenium使用博客导航 # 安装pip install lxml,使用xpath from lxml import etree import time from s…...

Angular模块化应用构建详解

文章目录 前言一、理解Angular模块&#xff08;NgModule&#xff09;二、创建功能模块三、懒加载模块以提高性能四、共享模块五、库模块六、最佳实践与注意事项七、案例研究&#xff1a;重构电子商务平台结语 前言 Angular是一款由Google支持的、用于构建动态Web应用程序的前端…...

51c大模型~合集89

我自己的原文哦~ https://blog.51cto.com/whaosoft/12815167 #OpenAI很会营销 而号称超强AI营销的灵感岛实测成效如何&#xff1f; OpenAI 是懂营销的&#xff0c;连续 12 天发布&#xff0c;每天一个新花样&#xff0c;如今刚过一半&#xff0c;热度依旧不减。 毫无疑问&…...

【蓝桥杯备战】Day 1

1.基础题目 LCR 018.验证回文串 给定一个字符串 s &#xff0c;验证 s 是否是 回文串 &#xff0c;只考虑字母和数字字符&#xff0c;可以忽略字母的大小写。 本题中&#xff0c;将空字符串定义为有效的 回文串 。 示例 1: 输入: s "A man, a plan, a canal: Panama…...

FedAdam算法:供给方信用,数据质量;更新一致性

FedAdam算法:供给方信用,数据质量;更新一致性 FedAdam算法概述 FedAdam是一种联邦学习(Federated Learning)算法。联邦学习是一种机器学习技术,它允许在多个设备或数据中心(称为客户端)上训练模型,而无需将数据集中到一个中央服务器,从而保护数据隐私。FedAdam主要用于…...

内存卡格式化后的数据恢复全攻略

一、内存卡格式化简述 内存卡&#xff0c;作为现代电子设备中不可或缺的存储媒介&#xff0c;广泛应用于手机、相机、行车记录仪等各类设备中。然而&#xff0c;在使用过程中&#xff0c;我们可能会遇到内存卡需要格式化的情况。格式化是一种将内存卡上的所有数据和文件系统清…...

介绍交叉熵损失(Cross-Entropy Loss)以及交叉熵在对比学习中的应用:中英双语

中文版 本文解释 交叉熵损失&#xff08;Cross-Entropy Loss&#xff09;&#xff0c;并结合对比学习的应用说明它如何工作&#xff0c;以及如何让正样本对更近、负样本对更远。 什么是交叉熵损失&#xff1f; 交叉熵损失是机器学习中常用的一种损失函数&#xff0c;主要用于…...

RabbitMQ的几个概念

注&#xff1a;这篇文章会随时添加新的内容&#xff0c;就是将RabbtiMQ中的概念添加到这里。助力大家的学习 自动ACK和手动ACK的区别 自动ACK和手动ACK是消息队列中两种不同的消息确认机制&#xff0c;它们在消息处理的可靠性和灵活性方面存在显著差异。 自动ACK&#xff08…...

Ollama部署大模型并安装WebUi

Ollama用于在本地运行和部署大型语言模型(LLMs)的工具,可以非常方便的部署本地大模型 安装 Linux curl -fsSL https://ollama.com/install.sh | sh我是ubuntu系统安装,其他系统可以看项目的开源地址有写 GitHub - ollama/ollama: Get up and running with Llama 3, Mist…...

Debedium如何忽略Oracle的purge命令

报错 截至目前3.0版本&#xff0c;Debezium的Oracle Connector并不支持purge table这个指令。 所以&#xff0c;在使用Debezium解析Oracle变更的时候&#xff0c;如果在源端执行了类似 purge table "$BIN… 的语句&#xff0c;就会导致Debezium罢工&#xff0c;日志里显…...

PlantUML 语言

PlantUML 是一种开源工具&#xff0c;用于通过简单的文本描述生成 UML 图。它支持多种 UML 图类型&#xff0c;如类图、序列图、用例图、活动图、组件图、状态图等。PlantUML 语言非常简洁&#xff0c;采用类似编程语言的语法&#xff0c;允许用户使用文本定义模型&#xff0c;…...

linux的 .so和.ko文件分别是什么?主要区别是什么?

前言&#xff1a; .so和.ko文件的主要区别在于它们的应用层次和功能不同。‌ 应用层次 .so文件‌&#xff1a;这是用户层的动态链接库&#xff08;Shared Object&#xff09;&#xff0c;主要用于用户态的程序中。 它用于动态链接&#xff0c;多个程序可以共享同一个库文件&…...

DockerHub与私有镜像仓库在容器化中的应用与管理

哈喽&#xff0c;大家好&#xff0c;我是左手python&#xff01; Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库&#xff0c;用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...

【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】

1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件&#xff08;System Property Definition File&#xff09;&#xff0c;用于声明和管理 Bluetooth 模块相…...

微信小程序云开发平台MySQL的连接方式

注&#xff1a;微信小程序云开发平台指的是腾讯云开发 先给结论&#xff1a;微信小程序云开发平台的MySQL&#xff0c;无法通过获取数据库连接信息的方式进行连接&#xff0c;连接只能通过云开发的SDK连接&#xff0c;具体要参考官方文档&#xff1a; 为什么&#xff1f; 因为…...

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...

AI书签管理工具开发全记录(十九):嵌入资源处理

1.前言 &#x1f4dd; 在上一篇文章中&#xff0c;我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源&#xff0c;方便后续将资源打包到一个可执行文件中。 2.embed介绍 &#x1f3af; Go 1.16 引入了革命性的 embed 包&#xff0c;彻底改变了静态资源管理的…...

html-<abbr> 缩写或首字母缩略词

定义与作用 <abbr> 标签用于表示缩写或首字母缩略词&#xff0c;它可以帮助用户更好地理解缩写的含义&#xff0c;尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时&#xff0c;会显示一个提示框。 示例&#x…...

C语言中提供的第三方库之哈希表实现

一. 简介 前面一篇文章简单学习了C语言中第三方库&#xff08;uthash库&#xff09;提供对哈希表的操作&#xff0c;文章如下&#xff1a; C语言中提供的第三方库uthash常用接口-CSDN博客 本文简单学习一下第三方库 uthash库对哈希表的操作。 二. uthash库哈希表操作示例 u…...

嵌入式常见 CPU 架构

架构类型架构厂商芯片厂商典型芯片特点与应用场景PICRISC (8/16 位)MicrochipMicrochipPIC16F877A、PIC18F4550简化指令集&#xff0c;单周期执行&#xff1b;低功耗、CIP 独立外设&#xff1b;用于家电、小电机控制、安防面板等嵌入式场景8051CISC (8 位)Intel&#xff08;原始…...

车载诊断架构 --- ZEVonUDS(J1979-3)简介第一篇

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 做到欲望极简,了解自己的真实欲望,不受外在潮流的影响,不盲从,不跟风。把自己的精力全部用在自己。一是去掉多余,凡事找规律,基础是诚信;二是…...

MyBatis-Plus 常用条件构造方法

1.常用条件方法 方法 说明eq等于 ne不等于 <>gt大于 >ge大于等于 >lt小于 <le小于等于 <betweenBETWEEN 值1 AND 值2notBetweenNOT BETWEEN 值1 AND 值2likeLIKE %值%notLikeNOT LIKE %值%likeLeftLIKE %值likeRightLIKE 值%isNull字段 IS NULLisNotNull字段…...