C++回顾(二)——const和引用

news2024/11/18 23:34:16

2.1 C++中的const

2.1.1 C与C++中const的比较

  • (1)C语言中的const
    C语言中 const修饰的变量是一个 常变量,本质还是变量,有自己的地址空间。

  • (2)C++中的const
    1、C++中 const 变量声明的是一个真正的常量,不是变量,所以编译器不会为该常量分配空间
    2、const 修饰的常量会被放到“符号表” 中;
    3、对const常量取地址,这一步操作会让编译器为该变量分配空间,分配的空间并不会被a使用;
    4、通过指针改变指向的空间的值,这个空间是编译器为常量分配的空间,但是常量的值并不在这个空间内 所以即使通过指针修改了这个空间的值,也不会影响到 a 本身。

  • (3)C++编译器对const常量的处理
    当碰见常量声明时,在符号表中放入常量 ==> 问题:那又如何解释取地址?
    编译过程中若发现对const使用了extern或者&操作符,则给对应的常量分配存储空间(兼容C),但是编译过程中若发现使用常量则直接以符号表中的值替换,即使给该常量分配了空间,也并不使用里面的值。
    在这里插入图片描述

2.1.2 const与#define

  • 相同之处
    C++中的const修饰的和#define定义的,是一个真正的常量,而不是C中变量(只读)。在const修饰的常量编译期间,就已经确定下来了

  • 不同之处
    (1)const常量是由编译器处理的,提供类型检查和作用域检查
    (2)宏定义由预处理器处理,单纯的文本替换

#include <iostream>

using namespace std;

void f()
{
	#define b 100
	const int c = 200;
}

int main()
{
	const int a = 1;     //C++中,const修饰的是常量,存放在符号表中
	//a++;
	int *p = (int *)&a;  //对const修饰的常量取地址,编译器分配了一个整形的长度,并且把数字1填写到对应的内存
	*p = 2;

	cout << a << endl;  //因为a是常量,所以用1替换a

	cout << b << endl;   //作用域不同
	//cout << c << endl; // 会报错

	return 0;
}

2.2 C++中的引用

2.2.1 普通引用

(1)变量名回顾

  • 变量名实质上是一段连续存储空间的别名,是一个标号(门牌号)
  • 程序中通过变量来申请并命名内存空间,通过变量的名字可以使用存储空间

(2) C++引用概念

  • 引用可以看作一个已定义变量的别名
  • 引用的语法:Type& name = var;
  • 引用在定义的时候必须初始化。
#include <iostream>

int main()
{
    // 定义一个int型变量a,在内存中占4个字节,
    // 变量名 a 就代表了这一块内存,或者说 a 是这块内存的别名
    int a = 10; 

    // 定义了一个引用变量 b ,它是 a 的别名,和 a 代表同一块内存空间
    // 对 b 的操作 和 对 a 的操作是一样的
    int& b = a;

    // 改变 b 等于改变了 a
    b = 20; 

    std::cout << " a = " << a << " b = " << b << std::endl;

    // a 与 b 代表同一块内存空间
    std::cout << &a << " " << &b << std::endl;

    return 0;
}

在这里插入图片描述

(3) 引用的意义

  • 1、引用作为其它变量的别名而存在,因此在一些场合可以代替指针
  • 2、引用相对于指针来说具有更好的可读性和实用性。
#include <iostream>

using namespace std;

void swap(int &x, int &y)   //int &x = m;
{
	y = x + y;
	x = y - x;
	y = y - x;
}

int main()
{
	int a = 100;

	int &b = a;     //定义引用b,初始化为a   b是a的别名
	b = 200;        //a = 200

	cout << a << endl;

	int m = 1, n = 2;
	swap(m, n);
	cout << "m = " << m << " n = " << n << endl;

	return 0;
}

在这里插入图片描述

(4)引用的本质

  • 1. 引用类型是否占内存空间?
    
struct Student
{
    char &a;
    char &b;
};
sizeof(struct Student) ====》 应该是输出 16 个字节(当作指针)
#include <iostream>

using namespace std;

struct Test
{
	int &a;
	int &b;
	char &c;      //引用的本质是常指针
};

int main()
{
	int a = 1;
	char ch = 'x';

	int &pa = a;     //引用定义的时候必须要初始化
	char &pc = ch;   //等价于 char *const pc = &ch;
	//int &f;

	cout << sizeof(pa) << endl;   //引用的长度就是其引用的对象的长度
	cout << sizeof(pc) << endl;
	//分析正常语法现象的时候,当做别名来分析,
	//但是分析奇怪的语法现象,需要考虑引用的实现
	cout << sizeof(struct Test) << endl;   
										   
	return 0;
}

在这里插入图片描述

  •  2. 引用的本质
    
  • 引用在C++中的内部实现是一个常指针
    Type& name <====> Type* const name

  • 1、C++编译器在编译过程中使用常指针作为引用的内部实现,因此引用所占用的空间大小与指针相同。

  • 2、从使用的角度,引用会让人误会其只是一个别名,没有自己的存储空间。这是C++为了实用性而做出的细节隐藏

    当我们使用引用语法的时,我们不去关心编译器引用是怎么做的
    当我们分析奇怪的语法现象的时,我们才去考虑c++编译器是怎么做的

(5)函数返回值为引用

  • 返回栈变量(不要返回局部变量的引用)
  • 返回全局变量或静态变量
#include <iostream>

using namespace std;

int g = 100;

int &f1()
{
	int a = 1;
	//return a;    //不要返回局部变量的引用
	return g;
}

int f2()
{
	return g;
}

int main()
{
	int &b = f1();

	f1() = 1;
	//f2() = 1;   //等价于100 = 1;

	return 0;
}

(6)指针引用

#include <iostream>
#include <cstdlib>
#include <cstring>

using namespace std;

void Init(char *&s)  //引用指针
{
	s = (char *)malloc(sizeof(char) * 100);
}

int main()
{
	char *s = NULL;

	Init(s);

	strcpy(s, "hello");

	cout << s << endl;

	return 0;
}

在这里插入图片描述

2.2.2 常引用

  • const & int e 相当于 const int * const e
  • 普通引用 相当于 int *const e1
  • 当使用常量(字面量)对const引用进行初始化时,C++编译器会为常量值分配空间,并将引用名作为这段空间的别名
  • 使用字面量对const引用初始化后,将生成一个只读变量
#include <iostream>

int main()
{
    int a = 10; 
    int &b = a;       // 普通引用

    int x = 20; 
    const int& y = x;   // 常引用  让变量y拥有只读属性,不能通过y改变x的值

    // 常引用 初始化 分为 2中情况
    // 1、用变量初始化 常引用
    {   
        int a1 = 20; 
        const int& b1 = a1; // a1 变量去初始化常引用
    }   
    // 2、用常量去初始化常引用
    {   
        const int a  = 40; // C++编译器把a放在符号表中

        // int& b = 41;    // 普通引用,引用一个常量,常量是没有地址空间的,这样的做法是不合法的

        // 使用常量去初始化常引用是合法的,C++编译器会为该引用分配空间,常量的值存储到分配的空间中去
        // 使用常量对 const引用 初始化后,将生成一个只读变量
        const int& b = 42; 

        int *p = (int *)&b;
        *p = 50; 
    
        std::cout << "b = " << b << std::endl;
    }

    return 0;
}

在这里插入图片描述

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

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

相关文章

24 openEuler管理进程-调度启动进程

文章目录24 openEuler管理进程-调度启动进程24.1 定时运行一批程序&#xff08;at&#xff09;24.1.1 at命令24.1.2 设置时间24.1.3 执行权限24.2 周期性运行一批程序&#xff08;cron&#xff09;24.2.1 运行机制24.2.2 crontab命令24.2.3 crontab文件24.2.4 编辑配置文件操作…

Linux基础命令-whereis查找命令及相关文件

文章目录 whereis 命令介绍 命令格式 基本参数 参考实例 1&#xff09;查找date命令及相关文件 2&#xff09;只显示date的二进制文件 3&#xff09;只显示源代码文件 4&#xff09;指定目录查找二进制文件 which与whereis对比 命令总结 whereis 命令介绍 通过帮助…

【TCSVT22】Pareto Refocusing for Drone-view Object Detection【航拍目标检测】

论文与代码论文地址&#xff1a;https://ieeexplore.ieee.org/document/9905640/代码地址&#xff1a;未开源背景与动机作者认为阻碍航拍场景目标检测发展的原因主要有以下两个&#xff1a;航拍图像中存在大量困难目标&#xff0c;文中作者把困难目标总结为小目标和遮挡的目标。…

机械革命旷世G16电脑开机变成绿屏了无法使用怎么办?

机械革命旷世G16电脑开机变成绿屏了无法使用怎么办&#xff1f;最近有用户使用的机械革命旷世G16电脑一开机之后&#xff0c;电脑屏幕就变成了绿色的&#xff0c;无法进行任何的操作。出现这个问题可能是因为电脑中病毒了&#xff0c;或者是系统出现故障。我们可以通过U盘来重新…

实习-----Mybatis 框架

Mybatis 框架ORM持久化介绍 了解什么是“持久化”即把数据&#xff08;如内存中的对象&#xff09;保存的磁盘的某一文件中ORM概念ORM&#xff0c;即Object Relational Mapping&#xff0c;它是对象关系映射的简称。它的作用是在关系型数据库和对象之间作一个映射&#xff0c;是…

CNTM 和ADA线下会议总结!

预计CNTM将会是ADA和Ocean共同孵化的第二个AI项M&#xff01;CNTM25号和ADA在台湾举办线下会议 并在近期CNTM和Ocean在一起交流AI技术&#xff0c;同时AGIX也是ADA和Ocean深度孵化的项目&#xff0c;预计CNTM将会是ADA和Ocean共同孵化的第二个AI项目&#xff01;什么是 CNTM &a…

【测试平台系列】如何停止测试任务执行

今天我们就玩点好玩的&#xff0c;和大家一起探讨&#xff1a;怎么停止一段python代码。之后我们将会运用到pity之中。 知识要点 本文需要大家对asyncio相关知识有一些了解&#xff0c;至于原理方面&#xff0c;大家可以自行查阅&#xff0c;因为我也没细看。 为什么要做这个…

Spring使用mongoDB步骤

1. 在Linux系统使用docker安装mongoDB 1.1. 安装 在docker运行的情况下&#xff0c;执行下述命令。 docker run \ -itd \ --name mongoDB \ -v mongoDB_db:/data/db \ -p 27017:27017 \ mongo:4.4 \ --auth执行docker ps后&#xff0c;出现下列行&#xff0c;即表示mongoDB安…

【项目精选】网络考试系统的设计与实现(源码+视频+论文)

点击下载源码 网络考试系统主要用于实现高校在线考试&#xff0c;基本功能包括&#xff1a;自动组卷、试卷发布、试卷批阅、试卷成绩统计等。本系统结构如下&#xff1a; &#xff08;1&#xff09;学生端&#xff1a; 登录模块&#xff1a;登录功能&#xff1b; 网络考试模块…

gdb openocd jlink arm-a9调试

连接关系是这样的&#xff1a;gdb —> openocd —>&#xff08;这里需要两个xx.cfg配置文件&#xff09; jlink —> arm-a9板子 具体流程是这样的&#xff1a; 给jlink&#xff08;硬件调试器&#xff09;安装驱动&#xff0c;用USB Driver Tool这个软件&#xff0c;…

02.24:图片的风格转换

Github网址&#xff1a;https://github.com/lengstrom/fast-style-transfer 在anaconda prompt中切换环境命令&#xff1a;activate 环境名 列出所有环境名&#xff1a;conda info --envs 安装环境&#xff1a;conda create -n 环境名 pythonx.x.x 删除某环境&#xff1a;co…

Spring Cloud Nacos源码讲解(八)- Nacos客户端服务订阅的事件机制剖析

Nacos客户端服务订阅的事件机制剖析 ​ 上次我们已经分析了Nacos客户端订阅的核心流程&#xff1a;Nacos客户端通过一个定时任务&#xff0c;每6秒从注册中心获取实例列表&#xff0c;当发现实例发生变化时&#xff0c;发布变更事件&#xff0c;订阅者进行业务处理&#xff0c…

WAF渗透攻防实践(16)

预备知识 WAF&#xff1a;WEB攻击一直是黑客攻击的主流手段&#xff0c;WAF作为网站安全基础设施的标配。Web Application Firewall&#xff0c;Web应用防火墙&#xff0c;通过执行一系列针对HTTP/HTTPS的安全策略来专门为Web应用提供保护的产品。 Nginx&#xff1a;Nginx 是…

京东10年经验测试工程师,整理出来的自动化测试学习路线,写给还在迷茫的你们

1、学习python基本语法。 2、上w3school这个网站&#xff08;2019年4月6日补充&#xff1a;网址是http://www.w3schools.com。但是现在这个网站被墙&#xff0c;而且出现众多山寨站点。。。这个网站的特点是你可以在网页上做一些练习&#xff0c;比如他教html的时候会让读者直…

Word的多级列表及自定义带级联编号有序列表的方法

1.多级列表的应用 输入列表时&#xff0c;列表项目符号或编号不应手动输入。可在输入文字后将光标放在文字所在段落&#xff0c;点击开始面板段落工具组的编号命令或者多级列表命令来生成编号。由于多级列表命令完全可以覆盖编号命令&#xff0c;且格式调整功能更强大&#xf…

ES数据迁移_snapshot(不需要安装其他软件)

参考文章&#xff1a; 三种常用的 Elasticsearch 数据迁移方案ES基于Snapshot&#xff08;快照&#xff09;的数据备份和还原CDH修改ElasticSearch配置文件不生效问题 目录1、更改老ES和新ES的config/elasticsearch.yml2、重启老ES&#xff0c;在老ES执行Postman中创建备份目录…

第45届世界技能大赛“网络安全”赛项浙江省选拔赛竞赛任务书

第45届世界技能大赛浙江省选拔赛竞赛任务书 一、竞赛时间 8:00-17:00&#xff0c;共计9小时。 二、竞赛阶段 竞赛阶段 任务阶段 竞赛任务 竞赛时间 分值 模块A 任务1 数据库安全加固 8:00-10:00 50 任务2 文件MD5校验 50 任务3 Linux系统服务渗透测试及安全加…

洛谷 P1208 [USACO1.3]混合牛奶 Mixing Milk

最后水一篇水题题解&#xff08;实在太水了&#xff09; # [USACO1.3]混合牛奶 Mixing Milk ## 题目描述 由于乳制品产业利润很低&#xff0c;所以降低原材料&#xff08;牛奶&#xff09;价格就变得十分重要。帮助 Marry 乳业找到最优的牛奶采购方案。 Marry 乳业从一些奶农手…

【RabbitMQ笔记03】消息队列RabbitMQ七种模式之WorkQueues工作队列模式

这篇文章&#xff0c;主要介绍消息队列RabbitMQ七种模式之WorkQueues工作队列模式。 目录 一、工作队列模式 1.1、什么是Work Queues模式 1.2、工作队列模式的使用 &#xff08;1&#xff09;引入依赖 &#xff08;2&#xff09;编写生产者 &#xff08;3&#xff09;编写…

如何提高您的网站速度更好的符合SEO规范

如果觉得文章对你有用请点赞与关注&#xff0c;每一份支持都是我坚持更新更优质内容的动力&#xff01;&#xff01;&#xff01;慢速网站会受到用户和搜索引擎的惩罚。用户跳出&#xff0c;搜索引擎可以降低您的排名。为了针对搜索引擎和用户优化您的网站&#xff0c;您的网站…