C++ Primer笔记002:引用/指针/const

news2024/11/18 3:32:22

文章目录

  • 1. 引用
    • 1.1 引用不是对象或变量
    • 1.2 引用必须初始化
    • 1.3 不能定义引用的引用
    • 1.4 引用类型要适配
    • 1.5 非const引用不能绑定字面值
  • 2. 指针
    • 2.1 指针和引用的区别
    • 2.2 指针的指针
    • 2.3 类型一致
    • 2.4 指针的引用
    • 2.5 void 型指针
  • 3. const
    • 3.1 const的基本作用
    • 3.2 对const变量的引用
    • 3.3 不能把一般引用与const变量进行绑定
    • 3.4 const变量的引用可以绑定字面值
    • 3.5 不存在const引用
  • 4. const与指针
    • 4.1 const变量的值不能改变
    • 4.2 const变量的指针可以存储非常量的地址
    • 4.3 const常量的存储地址
    • 4.4 const指针

1. 引用

1.1 引用不是对象或变量

引用就是对象或变量的别名,但引用不是对象或变量

int a=10;
int &b=a;

这里面,b就是变量a的另一个名字,对b操作就是对a操作,对a操作,b也会变化

void testreference()
{
	int a=10;
	int &b=a;
	b=5;
	cout<<a<<b<<endl;
	a=4;
	cout<<a<<b<<endl;
}

在这里插入图片描述

1.2 引用必须初始化

因为引用一定是某个变量的别名,引用一定是和变量绑定在一起的,所以引用必须初始化

int a=10;
int &b; <---错误

在这里插入图片描述

1.3 不能定义引用的引用

因为引用不是对象,但是引用又要绑定一个对象,所以不能定义引用的引用

int a=10;
int &b=a;
int &(&c)=a; <---错误

在这里插入图片描述

1.4 引用类型要适配

因为操作引用就是操作变量或者对象本身,所以对于内置类型,变量和其引用之间的类型要适配。

int a=10;
float &b=a; <---错误

在这里插入图片描述

1.5 非const引用不能绑定字面值

因为引用必须和变量进行绑定,所以非const引用不能绑定字面值

int a=10;
int &b=20; <---错误

在这里插入图片描述

所以,引用的基本特性就五个:

1.不是对象;
2.必须初始化;
3.不能定义引用的引用;
4.类型适配;
5.不能绑定字面值.

2. 指针

2.1 指针和引用的区别

指针就是变量的地址,可以通过引用访问变量,也可以通过指针访问变量,但是指针是对象,而引用不是,这是二者的根本区别

void testpointer()
{
	int a=10;
	int *p=&a;
	int *q;
	cout<<p<<endl<<q<<endl;
}

在这里插入图片描述

通过上述代码,可以知道,指针可以不初始化(只是为了演示,不要这样做),但是引用必须初始化

另外,&符号既能表示引用,也是取地址符号,当&出现在=左侧时,是引用,在=右边就是取地址

2.2 指针的指针

因为指针是一个对象,所以可以定义指针的指针,但是不能定义引用的引用

void testpointer()
{
	int a=10;;
	int *p=&a;
	int *q;
	int **pp = &p;
	cout<<p<<endl<<q<<endl;
	cout<<pp<<endl;
}

在这里插入图片描述

所以,指针的引用的不同点就是:

1.引用必须初始化,指针不用,
2.可以定义指针的指针,但是不能定义引用的引用,这两点的原因就是指针是变量,而引用不是(只是个别名)

2.3 类型一致

指针所指向的数据的类型要和指针的类型一致

float a=10;
int *p=&a;

在这里插入图片描述

2.4 指针的引用

因为指针是对象,引用不是,所以可以定义指针的引用,但是不能定义引用的指针

void testpr()
{
	int i=0;
	int *pi=&i;
	int *&pr=pi;
	cout<<pr<<endl<<pi<<endl;
	*pr=4;
	cout<<i<<endl;
}

在这里插入图片描述

int *&pr=pi;说明了如何定义一个指针的引用,可以从右向左读。
先看pr部分,我们知道有个对象叫pr;接着看到&pr,我们知道pr是一个引用
最后看到int *,就知道这个引用和一个int类型的指针绑定,这个指针就是pi
因为pr是pi的别名,所以对可以通过pr改变i。

2.5 void 型指针

void型指针可以存放任意类型的指针(包括二级指针),但是不能对void型指针解引用,所以void*指针可以保护数据所在的内存不被修改

void testvoidp()
{
	double d=1.2;
	double *pd=&d;
	int i=11;
	int *pi=&i;
	void *vp=pi;
	vp=pd;
	cout<<__func__<<endl;
	cout<<*vp;
}

在这里插入图片描述

3. const

3.1 const的基本作用

之前所讲的C++中的变量值,都是可以赋值的,如果我们不允许对变量赋值,那么就要将变量设置为const。

void testconst()
{
	const int c=10;
	c=20;
}

在这里插入图片描述

可见,只能对const变量进行初始化,不能对其赋值,因为const变量的值不能被改变

3.2 对const变量的引用

可以用const来修饰一个引用,称为对const变量的引用,对const变量的引用不能直接修改所绑定的对象(这个性质通常用于函数传参,使传的参数在函数中不能被改变)

void testconst()
{
	int i=2;
	const int &ri=i;
	ri=3;
}

在这里插入图片描述也就是说,无法通过ri来修改i的值

3.3 不能把一般引用与const变量进行绑定

因为const的变量无法修改,所以不能把一般引用const变量进行绑定

void testconst()
{
	const int c=10;
	int &ri=c;
}

如果可以通过一般引用来绑定const的变量,那么就可以通过该引用修改const变量,与const的属性相冲突,所以,不能用一般引用与const变量进行绑定。
在这里插入图片描述

3.4 const变量的引用可以绑定字面值

一般的引用不能与字面值进行绑定,但是const变量的引用可以绑定字面值(因为有const修饰)。而且,const变量的引用不仅可以绑定字面值,还可以绑定一般的对象(允许类型不匹配)

   void testconst()
   {
   	double d=1.2;
   	const int &rc=10;
   	const int &rc1=d;
   	cout<<rc<<endl<<rc1<<endl;
   }

在这里插入图片描述

正是因为const变量的引用几乎可以绑定任何对象,所以函数的参数一般都设定为const变量的引用,扩大了函数可传参数的范围

此外,由于是按引用传参,所以避免了拷贝,加快了代码的执行速度。

当执行const int &rc1=d;时,rc1并不是真正的和d绑定,而是绑定了一个临时变量,编译器会把这句代码转化成下面这样

const int tmp=d; //类型转换 double to int
const int &rc1=tmp;

在这种情况下,引用绑定的是一个临时量对象不是d本身,而是临时变量tmp

c++认为,常量引用可以绑定这个临时量,而普通引用就不能绑定这个临时量。因为c++认为,使用普通引用绑定一个对象,就是为了能通过引用对这个对象做改变。如果普通引用绑定的是一个临时量而不是对象本身,那么改变的是临时量而不是希望改变的那个对象,这种改变是无意义的。所以规定普通引用不能绑定到临时量上。

那么为什么常量引用就可以呢,因为常量是不能改变的。也就是说,不能通过常量引用去改变对象,那么绑定的是临时量还是对象都无所谓了,反正都不能做改变,也就不存在改变无意义的情况。

所以,常量引用可以绑定临时量,也就可以绑定非常量的对象、字面值,甚至是一般表达式,并且不用必须类型一致。

3.5 不存在const引用

4.因为引用并不是对象,所以不存在const引用(注意理解const变量的引用和const引用的区别)

void testconstreference()
{
	double d=1.2;
	int  &const rc=10; //const的引用
	const int &rc1=d;
	cout<<rc<<endl<<rc1<<endl;
}

在这里插入图片描述

const变量的引用与一般引用(见C++知识点——指针、引用基础)的区别

1.一般引用不能绑定字面值。但是const变量的引用就可以	
2.一般引用要与绑定的数据的类型一致,但是const变量的引用是个例外

4. const与指针

4.1 const变量的值不能改变

const变量的值不能改变,所以想要存放const变量的地址,就需要使用指向const变量的指针。

void testconstpointer()
{
	const int i=0;
	const int *pi=&i;
	cout<<pi<<endl;
}

在这里插入图片描述

4.2 const变量的指针可以存储非常量的地址

所以指向const变量的指针的基本作用就是存储const变量的地址,而且const变量的指针也可以存储非常量的地址(类型要匹配),因为pi本身是变量pi本身并不是const

void testconstpointer()
{
	int i=0;
	const int *pi=&i;
	cout<<pi<<endl;
}

在这里插入图片描述

4.3 const常量的存储地址

const变量i的地址不能使用指向非常量的指针来存储,而且非常量的指针也不能指向常量的指针,否则可以通过指针修改const变量。

void testconstpointer()
{
	const int i=0; 
	const int *pi=&i; //对
	int *p=&i; //错,p不是常量指针
	cout<<pi<<endl;
}

在这里插入图片描述

=======================================

void testconstpointer()
{
	const int i=0;
	const int *pi=&i;
	int *p=&pi;
	cout<<pi<<endl;
}

在这里插入图片描述

4.4 const指针

因为引用不是对象,但是指针是对象,所以存在const指针

void testconstpointer()
{
	int i=0;
	const int *const pi=&i;
	cout<<pi<<endl;
}

在这里插入图片描述

const int *const pi;的读法依然采用从右向左的读法

先看到pi,我们知道这是一个变量,接着看到const,我们知道他是一个const变量,然后看到*,我们知道这个是const的指针变量,看到const int我们知道这个const指针指向一个const int

因为pi用const修饰,所以pi中存储的地址值不能改变,也就是说,pi本身不能改变

void testconstpointer()
{
	int i=0;
	int j=0;
	const int *const pi=&i;
	pi=&j;
	cout<<pi<<endl;
}

在这里插入图片描述

因为pi指向const int,所以不能通过pi来改变指向的对象的值。

void testconstpointer()
{
	int i=0;
	int j=0;
	const int *pi=&i;
	*pi=10;
	cout<<pi<<endl;
}

在这里插入图片描述

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

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

相关文章

【VisualStudio 】VisualStudio2022 项目模板

引言 最近写项目已经形成的自己的套路&#xff1a;新建一个prism工程&#xff0c;添加主界面&#xff0c;配置界面&#xff0c;等&#xff0c;很多常用功能已经封装成项目进行复用。如果每次来了一个新的活&#xff0c;重新配置这些都是完全重复的工作&#xff08;大概需要十几…

第三章 Python 机器学习入门之C4.5决策树算法

系列文章目录 第一章 Python 机器学习入门之线性回归 第一章 Python 机器学习入门之梯度下降法 第一章 Python 机器学习入门之牛顿法 第二章 Python 机器学习入门之逻辑回归 番外 Python 机器学习入门之K近邻算法 番外 Python 机器学习入门之K-Means聚类算法 第三章 Python 机…

C++多态、虚函数、纯虚函数、抽象类

多态的概念 通俗来说&#xff0c;就是多种形态&#xff0c;具体点就是去完成某个行为&#xff0c;当不同的对象去完成时会产生出不同的状态。 举个简单的例子&#xff1a;抢红包&#xff0c;我们每个人都只需要点击一下红包&#xff0c;就会抢到金额。有些人能…

Windows11突然VM虚拟机无法运行报错与 Device/Credential Guard 不兼容

windows11长时间没用vmware,突然使用时打开报一下错&#xff1a; 解决方案&#xff1a; 以管理员身份运行“Windows Powershell (管理员)”&#xff08;Windows键X键&#xff09;&#xff0c;输入以下命令重启电脑。 bcdedit /set hypervisorlaunchtype off 注意&#xff1a…

有哪些专业的配音APP推荐?

作为当今社交媒体时代的一员&#xff0c;我们经常需要在各种场合中使用配音软件&#xff0c;无论是自制视频内容还是进行个人创作&#xff0c;一款好用且免费的配音软件显得很重要。今天给大家分享一款备受好评的免费配音软件&#xff0c;它不仅功能强大&#xff0c;而且操作简…

2023年【山东省安全员A证】考试内容及山东省安全员A证考试报名

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 山东省安全员A证考试内容是安全生产模拟考试一点通生成的&#xff0c;山东省安全员A证证模拟考试题库是根据山东省安全员A证最新版教材汇编出山东省安全员A证仿真模拟考试。2023年【山东省安全员A证】考试内容及山东省…

MS17010(永恒之蓝)漏洞实战

曾因苦难多壮志&#xff0c;不教红尘惑坚心。 工具检测 实战过程 使用搜索命令&#xff0c;搜索ms17_010 search ms17_010 搜索网段中主机漏洞 use auxiliary/scanner/smb/smb_ms17_010 照例&#xff0c;show options 看一下配置 设置网段&#xff0c;run运行就行了 使用攻…

leetcode 310 最小高度树

树是一个无向图&#xff0c;其中任何两个顶点只通过一条路径连接。 换句话说&#xff0c;一个任何没有简单环路的连通图都是一棵树。 给你一棵包含 n 个节点的树&#xff0c;标记为 0 到 n - 1 。给定数字 n 和一个有 n - 1 条无向边的 edges 列表&#xff08;每一个边都是一对…

代码随想录算法训练营第二十九天 | 回溯算法总结

​ 代码随想录算法训练营第二十九天 | 回溯算法总结 1. 组合问题 1.1 组合问题 在77. 组合中&#xff0c;我们开始用回溯法解决第一道题目&#xff1a;组合问题。 回溯算法跟k层for循环同样是暴力解法&#xff0c;为什么用回溯呢&#xff1f;回溯法的魅力&#xff0c;用递…

excel常用的几个函数

1、MID函数 通常用来返回返回指定字符串中的子串。 函数公式&#xff1a; MID(string, starting_at, extract_length) String&#xff08;必填&#xff09;&#xff1a;包含要提取字符的文本字符串 starting_at&#xff08;必填&#xff09;&#xff1a;文本中要提取的第一个字…

Tomcat及jdk安装下载及环境配置(超超超详解)

我是看了两篇博客安装配置好的 jdk 最详细jdk安装以及配置环境&#xff08;保姆级教程&#xff09;_安装jdk需要配置环境变量吗-CSDN博客 tomcat Tomcat的下载安装与配置及常见问题处理【Win11】 - 鞠雨童 - 博客园 (cnblogs.com) 本篇文章是我解决了很多朋友的tomcat配置问题总…

基于RIP的MGRE实验

题目及视图&#xff1a; 实验要求&#xff1a; 1.R5为ISP&#xff0c;只能进行IP地址配置&#xff0c;其所有地址均配为公有IP地址 2.R1和R5间使用PPP的PAP认证&#xff0c;R5为主认证 R2与R5之间使用ppp的CHAP认证&#xff0c;R5为主认证方 R3与R5之间使用HDLC封装 3.R1…

【C++学习笔记】引用

1. 概念 引用不是新定义一个变量&#xff0c;而是给已存在变量取了一个别名&#xff0c;编译器不会为引用变量开辟内存空 间&#xff0c;它和它引用的变量共用同一块内存空间。 比如&#xff1a;孙悟空&#xff0c;有人叫弼马温&#xff0c;也有人称为齐天大圣。 1.1 使用方…

计算机毕业设计 基于SpringBoot智慧养老中心管理系统的设计与实现 Javaweb项目 Java实战项目 前后端分离 文档报告 代码讲解 安装调试

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

粤嵌实训医疗项目--day01(Vue+SpringBoot)

目录 一、创建工作空间及配置Maven环境 二、创建springboot项目整合web操作 三、http请求参数获取及登录页面访问操作 四、数据库设计、数据库创建及导入sql 五、使用mybatis-plus逆向工程生成代码【vaccinum】 六、JavaEE三层架构概念及user查询实现 七、mybatis-plus逆…

安装与脏数据绕过_安全狗

1安全狗 1.1 环境准备 安全狗safedogwzApacheV3.5.exe&#xff0c;安装步骤省略&#xff0c; pikachu环境&#xff1a;https://zhuanlan.zhihu.com/p/568493971 安装注意事项&#xff1a;安装完后php和web服务都需要重启 注意事项&#xff1a;服务名php版本保持一致 安装过…

UG\NX二次开发 获取调色板CDF文件的内容

文章作者:里海 来源网站:《里海NX二次开发3000例专栏》 感谢粉丝订阅 感谢 迈克尔.卓别煷 订阅本专栏,非常感谢。 简介 UG\NX二次开发 获取调色板CDF文件的内容 文件->首选项->调色板 效果 代码 #include "me.hpp" #

使用Simple JWT提供认证服务(详细介绍access_token和refresh_token的使用)

文章目录 基本概念JSON Web Token&#xff08;JWT&#xff09;Simple JWT 主要用途Cookie、Session、Token的区别CookieSessionToken Token续签access_token 和 refresh_token时效设置 基本概念 JSON Web Token&#xff08;JWT&#xff09; JSON Web Token&#xff08;JWT&am…

探索大数据时代的关键技术:数据挖掘、可视化和数据仓库

文章目录 &#x1f31f; 大数据和数据分析技术&#x1f34a; 引言&#x1f34a; 数据挖掘&#x1f34a; 数据可视化&#x1f34a; 数据仓库&#x1f34a; 结论 &#x1f4d5;我是廖志伟&#xff0c;一名Java开发工程师、Java领域优质创作者、CSDN博客专家、51CTO专家博主、阿里…