C/C++const关键字详解(全网最全)

news2024/11/17 22:28:08

目录

1、const修饰普通变量

2、const修饰指针

(1)const修饰p:

(2)const修饰*p:

(3)const修饰p和*p

4、const修饰数组

5、const修饰函数形参

(1)const修饰普通形参变量

(2)const修饰指针形参

(3)const修饰引用形参

6、const 修饰函数返回值

(1)const修饰普通类型的返回值

(2)const修饰指针类型的返回值    

7、const修饰成员变量

8、const修饰成员函数


1、const修饰普通变量

用const修饰普通变量实际上就是定义了一个常量,以下两种定义形式在本质上是一样的。它的含义是:const修饰的类型为TYPE的变量value是不可变的。 一般对于const变量名都是全大写的。

TYPE const ValueName = value; 

const TYPE ValueName = value;

如果我们强行修改const定义的常量,就会报错。在这里插入图片描述

 实际上,虽然不能直接对常变量进行修改,但是我们可以通过指针对常变量进行修改:

在这里插入图片描述

所以当指针指向const常变量时,为避免通过指针修改const常变量,我们应当相应地用const指针指向const常变量。

const int AMOUNT = 100;
int const *p = &AMOUNT;

用const定义的常量有什么作用呢?

假设我们在代码中经常使用到一个数字100,我们可以定义一个常量,让常量的值100:

const int AMOUNT = 100;

如果我们没定义常量,我们需要将100修改为200,需要将代码出现的所有100依次修改为200,而如果我们定义了常量,我们只需要修改常变量的值为200即可,这样就增加了代码的可维护性。

如果将const改为外部连接,作用于扩大至全局,编译时会分配内存,并且可以不进行初始化,仅仅作为声明,编译器认为在程序其他地方进行了定义。

extend const int ValueName = value;

2、const修饰指针

(1)const修饰p:

int i = 10;
int* const p = &i;

const修饰指针p表示指针不可修改,即一旦得到了某个变量的地址,不能再指向其它变量:

int i = 10;
int * const p = &i;
p++;//p指针指向下一个元素,错误

虽然指针不可修改,但是可以修改指针所指向的变量的值:

int i = 10;
int * const p = &i;
*p = 26;//没问题

(2)const修饰*p:

int i = 10;
const int * p = &i;

const修饰*p表示不可通过指针修改其所指变量的值:

int i = 10;
const int* p = &i;
*p = 26;//通过指针修改其所指变量的值,错误

虽然不可以通过指针修改指针所指变量的值,但是变量i本身可以做任何变化,如:

int i = 10;
const int* p = &i;
i=26;
i++;

p也可以变:

p = &j;

(3)const修饰p和*p

const int* const p;

const修饰p和*p表示指针不能变,指针所指的变量也不能变。

注意以下的区别:

int i;
const int* p1 = &i;//不能通过指针修改
int const* p2 = &i;//不能通过指针修改
int *const p3 = &i;//指针不能修改
/*判断哪个被const了的标志是const在*的前面还是后面*/

4、const修饰数组

数组变量实际上就是const的指针,所以不能直接赋值:

int a[]
//a--->int* const a;

const修饰数组表明数组的每个元素都是const int,无法修改,所以必须通过初始化进行赋值,否则写出来后就无法进行赋值了。

const int a[]
//a---->const int * const a;

5、const修饰函数形参

(1)const修饰普通形参变量

void function(const int Var);

这表示形参不会发生改变,但实际上这是没有意义的,因为我们通常是为了保证外部的实参数据不发生变化,这里形参实际上是实参的拷贝,实参本来就不会发生变化。

(2)const修饰指针形参

void function(const char* Var);

我们把外部实参的地址赋值给用const修饰的指针形参,这样我们就无法通过指针修改其所指的外部实参,保护了数据的安全性。

但如果是这种const指针形参就毫无意义:

void function(char* const Var);

因为这表示指针形参不会改变,但是我们依然可以通过指针修改传过来的外部实参,无法保证外部数据的安全性。

(3)const修饰引用形参

void function(const Type& Var); //引用参数在函数内不可以改变

参数为引用,将外部实参传递给引用形参,传递的是外部实参本身,无需进行拷贝,增加了效率,同时参数是const引用,无法通过引用修改实参,保证了外部数据的安全性。

注:

如果函数参数是非const的引用/指针,它就不能接收const变量(地址),因为会造成权限的放大,会报错,它只能接收非const变量(地址),而如果函数参数是const的引用/指针,它既可以接收const变量(地址),也可以接收非const变量(地址),这是权限的缩小,没问题,如果函数是const普通变量,那么它可以接收const变量,也可以接收非const变量,因为不会造成权限的放大。

6、const 修饰函数返回值

const修饰函数返回值其实用的并不是很多。

(1)const修饰普通类型的返回值

const int fun1();

这个实际上是毫无意义的,因为返回的实际上是临时变量,临时变量本身就具有常性。

(2)const修饰指针类型的返回值    

第一种情况是const修饰*p:

const int * fun2();
const int *p = fun2();//调用正常
int* p2 = fun2();//调用失败

这里简单分析下第三句代码调用失败的原因,因为fun2()实际上是一个const int*指针,我们无法通过指针修改其所指变量,而把fun2()这个const  int*指针赋值给p2后,p2是非const指针,可以通过指针修改其所指变量,这就造成了指针所指变量的访问权限的放大,因此调用失败。

第二种情况就是const修饰p

int* const fun3();
int * const p = fun3();//调用正常
int *p2 = fun3();//调用正常 

看第三句代码,为什么这种情况,返回的int* const指针可以赋值给非const指针呢?

我们可以把fun3()看作一个int * const指针,尽管该指针不可以修改,但是我们可以通过该指针修改其所指变量,赋值给p2后,我们依然可以通过指针修改其所指变量,对指针所指变量的访问权限没有发生变化,这样的赋值当然没有问题了。

7、const修饰成员变量

const修饰类的成员变量,表示成员常量,不能被修改,同时它只能在初始化列表中赋值。   

 class A

    { 

        …

        const int nValue;//成员常量不能被修改

        …

        A(int x): nValue(x) { };//只能在初始化列表中赋值

     } 

8、const修饰成员函数

将const修饰的“成员函数”称之为const成员函数。this指针的类型是:类类型* const this,即成员函数中,不能修改this指针,但是其所指向对象的成员变量可以被修改,const修饰类成员函数,实际上就是将this限定为:const 类类型 * const this,表明在该成员函数中不能对调用对象的任何成员进行修改,起到保护对象的作用。

格式: 将const关键字放在函数的括号后面

class Date
{
public:
    void Display()const
    {
        cout<<_year<<endl;
    }
    //该成员函数实际上是这样
    /*
    void Display(const Date *const this)
    {
        cout<<this->_year<<endl;
    }*/
private:
    int _year;
    int _month;
    int _day;
};

关于const成员函数,以下几点需要我们注意:

  1. 就像尽可能地将函数形参中的引用和指针声明为const一样,只要成员函数不修改调用对象,就应该将其声明为const,这样既可以避免调用对象被修改,而且普通对象和const对象都可以调用(不会造成读写权限的放大)。
  2. 前面提到过,读写权限只能缩小,不能放大,所以,const对象只能调用const成员函数,不可以调用非const成员函数,因为const对象不可以被修改,如果const对象调用非const成员函数,非const成员函数可以修改调用它的const对象,这是权限的放大,会报错。非const对象可以调用非const成员函数,也可以调用const成员函数,因为这是权限的缩小。
  3. const修饰类的成员函数,则该成员函数不能调用类中任何非const成员函数,因为非const成员函数可能会对const对象造成修改,引起权限的放大。
  4. const成员函数能够访问对象的const成员,而其他成员函数不可以。

以上是鄙人对const关键字作用的一些理解,因水平有限,内容之处难免有所缺陷,欢迎各位批评指正......

·       

·            

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【数据结构】6.4 图的存储结构

文章目录6.4.1 邻接矩阵&#xff08;数组&#xff09;表示法无向图的邻接矩阵无向图邻接矩阵的特点有向图的邻接矩阵有向图邻接矩阵的特点网&#xff08;有权图&#xff09;的邻接矩阵采用邻接矩阵创建无向网邻接矩阵的优缺点6.4.2 邻接表&#xff08;链式&#xff09;无向图的…

【人工智能原理自学】初识Keras:轻松完成神经网络模型搭建

&#x1f60a;你好&#xff0c;我是小航&#xff0c;一个正在变秃、变强的文艺倾年。 &#x1f514;笔记来自B站UP主Ele实验室的《小白也能听懂的人工智能原理》。 &#x1f514;本文讲解初识Keras&#xff1a;轻松完成神经网络模型搭建&#xff0c;一起卷起来叭&#xff01; 目…

Eureka入门

Eureka入门Eureka入门什么是Eureka构建项目demo服务拆分远程调用创建Pom聚合工程Eureka使用搭建注册中心注册服务远程调用出现的问题Eureka入门 什么是Eureka Eureka是SpringCloud提供的注册中心&#xff0c;用来解决微服务之间远程调用问题&#xff0c;如&#xff1a; 消费…

交通流的微观模型研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Redis原理篇(四)内存回收

Redis之所以性能强&#xff0c;最主要原因是基于内存存储。但是单节点的Redis其内存大小不宜过大&#xff0c;会影响持久化或主从同步性能。 可以通过配置文件来设置最大内存 # maxmemory <bytes> maxmemory 1gb一、过期策略 可以通过expire命令给Redis的key设置TTL …

【C++算法图解专栏】一篇文章带你掌握高精度加减乘除运算

✍个人博客&#xff1a;https://blog.csdn.net/Newin2020?spm1011.2415.3001.5343 &#x1f4e3;专栏定位&#xff1a;为 0 基础刚入门数据结构与算法的小伙伴提供详细的讲解&#xff0c;也欢迎大佬们一起交流~ &#x1f4da;专栏地址&#xff1a;https://blog.csdn.net/Newin…

Java 异常 笔记

异常体系结构 异常分为Error和Exception。Error通常是灾难性错误&#xff0c;一般发生时&#xff0c;JVM选择终止程序执行&#xff1b;Exception通常可在程序中进行处理&#xff0c;尽量避免 Exception分支中有一个重要子类RuntimeException&#xff0c;运行时异常 ArrayInd…

数据库,计算机网络、操作系统刷题笔记34

数据库&#xff0c;计算机网络、操作系统刷题笔记34 2022找工作是学历、能力和运气的超强结合体&#xff0c;遇到寒冬&#xff0c;大厂不招人&#xff0c;可能很多算法学生都得去找开发&#xff0c;测开 测开的话&#xff0c;你就得学数据库&#xff0c;sql&#xff0c;oracle…

深入理解Promise

Promise的前提概念 Promise是一个构造函数&#xff0c;用来生成Promise实例 Promise构造函数接受一个函数作为参数&#xff0c;该函数有两个参数&#xff0c;分别是resolve和reject resolve&#xff1a;成功时的回调 reject&#xff1a;失败时的回调 Promise分别有三个状态 1…

行人属性识别研究综述(一)

文章目录摘要1、简介2 问题的表述和挑战3 标准3.1 数据集3.2 评价标准4 行人属性识别的常规流程4.1 多任务学习4.2 多标签学习5 深度神经网络&#x1f407;&#x1f407;&#x1f407;&#x1f407;&#x1f407;&#x1f407;&#x1f407; 欢迎阅读 【AI浩】 的博客&#x1f…

C#上位机基础学习_基于S7.Net实现读取S7-1500PLC中的字符串变量

C#上位机基础学习_基于S7.Net实现读取S7-1500PLC中的字符串变量 如下图所示,首先在TIA博途中创建一个项目,添加一个1500PLC,添加一个DB块,在DB块中添加几个字符串变量, 如下图所示,打开Visual Studio 2019,新建一个项目,在Form1中添加一个按钮和一个文本框, 如下图…

linux——高级信号

高级信号的收发发&#xff1a;siquequ收&#xff1a;sigaction() 包含三个元素num,sigaction()函数&#xff0c;备份num ->signumsigaction是一个结构体&#xff0c;需额外配置再传进来备份直接忽略&#xff0c;代表不需要备份sigaction结构体又包含四个元素sa_handler&…

Git进阶:修改上次提交 git commit --amend

一、问题说明 git commit 后&#xff0c;发现刚才的备注写错了&#xff0c;或者代码漏掉了&#xff0c;这时我们肯定是想取消刚才的提交。此刻有两种方法 &#xff08;1&#xff09;使用git reset命令将刚才的提交会退掉。需要注意的是git reset --soft 和git reset --hard的区…

【附源码】国内首届Discord场景创意编程开源项目

以下开源项目是由环信联合华为举办的《国内首届Discord场景创意编程赛》作品&#xff0c;附源码&#xff0c;一键即用。 一、 模拟器游戏直播-新新人类 新新人类模拟器游戏直播基于环信超级社区Demo构建&#xff0c;增加以“video-x”命名的新型Channel&#xff0c;用户可在本…

Java三目运算符导致 NPE

在三目运算符中&#xff0c;表达式 1 和 2 在涉及算术计算或数据类型转换时&#xff0c;会触发自动拆箱。当其中的操作数为 null 值时&#xff0c;会导致 NPE 。 一、基础知识 三目运算符 三目运算符是 Java 语言中的重要组成部分&#xff0c;它也是唯一有 3 个操作数的运算…

Linux常用命令——tempfile命令

在线Linux命令查询工具(http://www.lzltool.com/LinuxCommand) tempfile shell中给临时文件命名 补充说明 有时候在写Shell脚本的时候需要一些临时存储数据的才做&#xff0c;最适合存储临时文件数据的位置就是/tmp&#xff0c;因为该目录中所有的内容在系统重启后就会被清…

LInux(三)程序地址空间、内存管理

目录 一、程序地址空间 二、内存管理方式 1、分段式内存管理 2、分页式内存管理 3、段页式内存管理 三、关于内存管理内容补充&#xff08;分页式&#xff09; 1、页表简单呈现 2、访问权限位 3、缺页中断 4.内存置换算法 一、程序地址空间 创建父子进程同时访问同一变量…

正式发布丨Azure OpenAI Service

Azure OpenAI 服务现已在微软全球 Azure 平台正式发布&#xff0c;这是微软人工智能大众化以及与 OpenAI 持续合作的又一里程碑。 大型语言模型正迅速成为用户无限创新、应用 AI 解决重要问题的平台。随着 Azure OpenAI 服务的正式发布&#xff0c;更多企业用户可以访问世界先…

在线支付系列【5】支付安全之数字证书

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 文章目录公钥信任问题数字证书颁发流程使用流程SSL数字证书HTTPSSSL/TLS 证书如何申请SSL 证书使用keytool 生成ssl证书通信过程公钥信任问题 之前我们使用对称、非对称加密、信息摘要、数字签名&#…

DPDK系列之一基础环境搭建

一、DPDK是什么 DPDK,Data Plane Development Kit&#xff0c;数据平面开发套装&#xff0c;它还有一个兄弟SPDK&#xff0c;专门用来做存储优化的。它主要运行于Linux&#xff0c;是由Intel几家公司共同开发&#xff0c;用于快速处理数据的一个网络开发工具套装。更详细的说明…