c++——引用(语法、引用特性、常引用、函数返回值引用和指针与引用的不同点)

news2024/12/26 1:00:02

c++中的引用

一、引用

1、引用的概念:给变量取别名。

形式:原类型名& 别名 = 引用实体旧名;

2、特性:

①引用定义时必须初始化
②引用一旦初始化之后就不能再改变引用的指向
③不能引用NULL
④&再等号的左边为引用,在等号的右边为取地址

引用在定义时必须初始化。否则不知道引用的哪一个

#include <iostream>
using namespace std;
int main(){
	int a=10;
	int& ra;//编译时出错
    int& r = a;
    return 0;
}

引用一旦引用一个实体,再也不能引用其它实体。不然就是赋值。

#include <iostream>
using namespace std;
int main(){
	int a=10;
    int b=20;
	int& ra=a;
	ra =b;//赋值 //ra是前面引用a的,ra再次引用就是等于赋值了
    return 0;
}

3.常引用

①一个常量的引用也应该是一个常量

#include <iostream>
using namespace std;
int main(){
	const int a=10;//const修饰定义的常量
	//int& ra=a;编译时出错
	const int& ra = a;
	system("pause");  
    int i =10;
    const int &r_i = i;
return 0;

原因: 变量a是可读不可改写的,引用ra是可读可改写的,如果对ra改写,就会对a产生影响。所以会编译出错。

②一个变量也可以用一个常量引用来引用

#include <iostream>
using namespace std;
int main(){
	int a=10;
	int& ra=a;
	const int& rb = a;//可以用一个常量rb来引用
return 0;

原因: 变量a是可读可改写的,引用rb是可读不可改写的。这是允许的。

还有一种特殊情况,当引用时发生隐式转化,用常引用接收可以。
如下:

#include <iostream>
using namespace std;
int main(){
	double a=3.14;
	//int& ra=a;//编译出错
	const int& rb = a;//正确
return 0;
}

原因: 当发生隐式转化时,会产生一个临时变量,改临时变量先将原来值进行转化,再赋值给新值。重要的原因是,该临时变量具有常量性质(可读不可改写)。所以需要常引用接收。
用上面的例子就是,rb引用a时发生隐式转化,此时会创建一个临时变量tmp,先将a转化为int,再将tmp值赋给rb。
在这里插入图片描述

注意 是引用的时候发生隐式转化时,提前隐式转化,再引用不需要常引用接收。

#include <iostream>
using namespace std;
int main(){
	double a=3.14;
	int c = a;//提前转化,再引用
	int& rc = c;//正确
return 0;
}

4、一个变量可以有多个引用。

#include <iostream>
using namespace std;
//这样都是正确的,一块空间的多个命名
int main(){
	int a=10;
	int& ra=a;
	int& rb = a;
	int& rc = ra;
    return 0;
}

结论:引用时,读写权限可以缩小不可以放大。

5、引用场景

①引用变量

int a = 10;
int& b = a;//给a取别名为b
b = 100;
int& ra=a;
int& rb = a;
int& rc = ra;
cout << "a == " << a << endl;

一个变量可以有多个引用

②引用数组

int a[4] = {1,2,3,4};
int (&arr)[4] = a;

6、在函数中的引用

①做形参

#include <iostream>
using namespace std;
void swap(int& a,int& b){
    int temp=a;
    a=b;
    b=temp;
}
int main()
{
    int x=10;
    int y=20;
    swap(x,y);
    return 0;
}

②做返回值

#include <iostream>
using namespace std;
int& count(){
    static int n=0;
    n++return n;
}
int main()
{
    int& a=count();
    cout<<a<<endl;
    return 0;
}

1.这里为什么要用static修饰n,如果不用static修饰会怎么样?

上面返回值为int&引用,在main函数中用引用a来接收。我们知道引用并不开辟空间,所以a并没有开辟空间,而是n的引用,也就是n和a的地址会相同。如果不用static修饰n,则n变量在栈上开辟空间,如果调用一个其它的函数,a的值很有可能会发生改变,这样a的值得不到保障。但是static修饰的变量在静态区存储,值并不会发生改变。

2.返回值不是引用的,如果想用引用来接收,必须使用常引用。

#include<iostream>
using namespace std;
int count(){
	int n = 0;
	n++;
	return n;
}
int main(){
	//int& a = count();//编译错误
	const int& a = count();//正确
return 0;
}

原因:和隐式转化差不多,当返回的时候,会生成一个临时变量,该临时变量的值等于返回值。并且,该返回值具有常量性质。

3.引用做返回值,也可以不使用引用来接收,这样值就得到了保障。

#include<iostream>
using namespace std;
int count(){
	int n = 0;
	n++;
	return n;
}
int main()
{
    int a = count();
    return 0;
}

原因:此时main函数里的a开辟空间,与n无关了,或者说与返回时创建的临时变量无关了,只是将它的值赋给了a。

二、引用的效率

传值和传引用,返回值和返回引用的效率说明:
以值作为参数或者返回值,在传参数和返回期间,函数不会直接传递给实参或者将变量本身直接返回,而是传递实参或者返回变量的一份临时拷贝,由上可知要开辟临时空间。因此效率时很低下的,而使用引用作为参数和返回值时,并不需要开辟空间。
因此传值,返回值比传引用和返回引用的效率低。

三、指针与引用的不同点

1、引用在概念上是定义一个变量的别名,指针存储一个变量的地址。
2、引用在定义时必须初始化,指针没有要求。
3、引用在引用一个实体后,不能再引用其它实体,指针在任何时候都可以指向一个同类型的实体,改变指向。
4、没有NULL引用,指针可以指向NULL。
5、在sizeof中含义不同,引用的结果是引用类型的大小(int&类型是int)。但是指针始终是地址空间所占字节大小(在32位机器下占4字节空间,在64位机器下占8字节空间)
6、有多级指针,没有多级引用。
7、访问实体不同,指针需要显式解引用,引用编译器自己处理。
8、引用加1,为实体数值加1。指针加1,偏移一个单位。
9、引用比指针使用起来相对安全些。

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

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

相关文章

FPGA原理与结构——ROM IP的使用与测试

一、前言 本文介绍Block Memory Generator v8.4 IP核 实现ROM&#xff0c;在学习一个IP核的使用之前&#xff0c;首先需要对于IP核的具体参数和原理有一个基本的了解&#xff0c;具体可以参考&#xff1a; FPGA原理与结构——块RAM&#xff08;Block RAM,BRAM&#xff09;http…

04_18内存反碎片技术,什么时候适合进行内存碎片整理

前言 内存碎片分为内部碎片和外部碎片&#xff0c;内部碎片指内存页里面的碎片&#xff0c;外部碎片指空闲的内存页分散&#xff0c;很难找到一组物理地址连续的空间内存页&#xff0c;无法满足超过一页的内存分配请求。 虚拟可移动区域 可移动区域&#xff08;ZONE_MOVABLE…

A 题国际旅游网络的大数据分析-详细解析与代码答案(2023 年全国高校数据统计与调查分析挑战赛

请你们进行数据统计与调查分析&#xff0c;使用附件中的数据&#xff0c;回答下列问题&#xff1a; ⚫ 问题 1: 请进行分类汇总统计&#xff0c;计算不同国家 1995 年至 2020 年累计旅游总人数&#xff0c;从哪个国家旅游出发的人数最多&#xff0c;哪个国家旅游到达的人数最多…

【JavaEE】面向切面编程AOP是什么-Spring AOP框架的基本使用

【JavaEE】Spring AOP&#xff08;1&#xff09; 文章目录 【JavaEE】Spring AOP&#xff08;1&#xff09;1. Spring AOP 是什么1.1 AOP 与 Spring AOP1.2 没有AOP的世界是怎样的1.3 AOP是什么 2. Spring AOP 框架的学习2.1 AOP的组成2.1.1 Aspect 切面2.1.2 Pointcut 切点2.1…

微人事 部门管理 模块 (十五)

部门管理的树展示和搜索 数据展示页是个树&#xff0c;我们一次性把数据加载出来也可以通过点一次id加载查询出来出来子部门&#xff0c;我们用一次拿到说有json数据加载出来 数据不多可以用递归&#xff0c;数据很多就用懒加载的方式 由于子部门比较深就不适合&#xff0c;权…

# 59. python的类与对象-更新

[目录] 文章目录 59. python的类与对象-更新1.面向对象编程2.什么是类3.什么是对象4.如何描述对象5.对象的属性和方法6.Python中的类7.type()函数查看数据类型8.类在Python中的应用9.总结 【正文】 59. python的类与对象-更新 1.面向对象编程 本节内容特别抽象&#xff0c;初…

Web3和去中心化:互联网的下一个演化阶段

文章目录 Web3和去中心化的定义Web3&#xff1a;去中心化&#xff1a; 为什么Web3和去中心化如此重要&#xff1f;数据隐私和安全&#xff1a;去中心化的创新&#xff1a;去除中间商&#xff1a; Web3和去中心化的应用领域去中心化金融&#xff08;DeFi&#xff09;&#xff1a…

wustojc2003求整数均值

#include <stdio.h> int main() {int a,b,c,d;double A;scanf("%d%d%d%d",&a,&b,&c,&d);A(double)((abcd)/4.0);//强转成doubleprintf("Sum %d\n",abcd);printf("Average %.2lf",A);return 0;}

C++笔记之基类指针动态地指向某一个子类情况列举

C笔记之基类指针动态地指向某一个子类情况列举 code review! 文章目录 C笔记之基类指针动态地指向某一个子类情况列举1.基本的多态示例2.基类中的成员函数可以设置为纯虚函数3.将基本示例修改为使用智能指针并在堆上实例化子类4.父类指针指向基类后&#xff0c;可以去调用只有…

【JUC系列-01】深入理解JMM内存模型的底层实现原理

一&#xff0c;深入理解JMM内存模型 1&#xff0c;什么是可见性 在谈jmm的内存模型之前&#xff0c;先了解一下并发并发编程的三大特性&#xff0c;分别是&#xff1a;可见性&#xff0c;原子性&#xff0c;有序性。可见性指的就是当一个线程修改某个变量的值之后&#xff0c…

shell脚本之sed

sed sed 即 Stream EDitor&#xff0c;和 vi 不同&#xff0c;sed是行编辑器 基本用法 sed [选项] 自身脚本用法 [支持输入标准输入管道] 常用选项&#xff1a;-n 不输出模式空间内容到屏幕&#xff0c;即不自动打印-e 多点编辑-f FILE 从指定文件中读取编辑脚本-r, -E 使用…

【TypeScript】内置对象

JavaScript 中很多内置对象&#xff0c;可以直接在 TypeScript 中当做定义好了的类型。 ECMAScript 的内置对象 Boolean、Number、String、RegExp、Date、Error、XMLHttpRequest 等 let num: Number new Number(1) let date: Date new Date() let reg: RegExp new RegExp(…

WTF Langchain极简入门: 03. 数据连接

加载文档 langchain提供多种文档加载器&#xff0c;支持多种格式、来源的文件。可以从本地存储系统加载文件&#xff0c;也可以从网上加载远端文件。想了解LangChain所支持的所有文档加载器&#xff0c;请参考Document Loaders。 在本系列课程中&#xff0c;我们将使用最基本…

Docker 搭建 LNMP + Wordpress(详细步骤)

目录 一、项目模拟 1. 项目环境 2. 服务器环境 3.任务需求 二、Linux 系统基础镜像 三、Nginx 1. 建立工作目录 2. 编写 Dockerfile 脚本 3. 准备 nginx.conf 配置文件 4. 生成镜像 5. 创建自定义网络 6. 启动镜像容器 7. 验证 nginx 四、Mysql 1.…

快速学习GO语言总结

备注&#xff1a;本博客将自己初步学习GO的总结进行分享&#xff0c;希望大家通过本博客可以在短时间内快速掌握GO的基本程序编码能力&#xff0c;如有错误请留言指正&#xff0c;谢谢&#xff01; 一、初步了解Go语言 &#xff08;一&#xff09;Go语言诞生的主要问题和目标…

shell脚本——expect脚本免交互

目录 一.Here Document 1.1.定义 1.2.多行重定向 二.expect实现免交互 2.1.基础免交互改密码 2.2.expect定义 2.3.expect基本命令 2.4.expect实现免交互ssh主机 一.Here Document 1.1.定义 使用I/O重定向的方式将命令列表提供给交互式程序&#xff0c;是标准输 入的一…

uniapp开发小程序,上传图片和视频功能

1.需求&#xff1a; 可以上传图片和视频&#xff0c;并且都可以删除&#xff0c;图片可以预览。 2.效果图 3.代码&#xff1a; <template><!-- 上传start --><view style"display: flex; flex-wrap: wrap;"><view class"update-file&quo…

FPGA解析串口指令控制spi flash完成连续写、读、擦除数据

前言 最近在收拾抽屉时找到一个某宝的spi flash模块&#xff0c;如下图所示&#xff0c;我就想用能不能串口来读写flash&#xff0c;大致过程就是&#xff0c;串口向fpga发送一条指令&#xff0c;fpga解析出指令控制flah&#xff0c;这个指令协议目前就是&#xff1a; 55 AA …

达梦数据库表空间创建和管理

概述 本文将介绍在达梦数据库如何创建和管理表空间。 1.创建表空间 1.1表空间个数限制 理论上最多允许有65535个表空间&#xff0c;但用户允许创建的表空间 ID 取值范围为0~32767&#xff0c; 超过 32767 的只允许系统使用&#xff0c;ID 由系统自动分配&#xff0c;ID不能…

周易卦爻解读笔记——小过

第六十二卦小过 雷山小过 震上艮下 小过卦为母卦&#xff0c;象征小有过越。 小过卦是中孚卦的错卦&#xff0c;序卦传【有信者必行之&#xff0c;故受之以小过】 小过&#xff1a;亨&#xff0c;利贞&#xff0c;可小事&#xff0c;不可大事。飞鸟遗之音&#xff0c;不宜上宜…