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

C++ 黑马 引用

 一,  引用的基本概念

前言:由于VS2022过去先进,所以有很多的东西是错误的,但是VS2022编译器会自动优化,所以学习的话推荐使用Dev-C++,版本较老,当我们步入项目的时候就可以避免很多的错误,再使用VS2022也不迟


引用的作用: 给变量起别名

语法: 数据类型 &别名 = 原名

示例:

#include<iostream>using namespace std;int main() {int a = 10;int &b = a;cout << "a = " << a << endl;cout << "b = " << b << endl;b = 100;cout << "a = " << a << endl;cout << "b = " << b << endl;system("pause");return 0;
}

编译输出:

a = 10
b = 10
a = 100
b = 100
请按任意键继续. . .

得出的结果是,可以利用去修改它指向的变量,类似于指针一样的操作

二,  引用的注意事项

1  引用需要进行初始化
2  引用初始化之后,就不可以改变

int main() {int a = 10;int b = 20;//int &c; //错误,引用必须初始化int &c = a; //一旦初始化后,就不可以更改c = b; //这是赋值操作,不是更改引用cout << "a = " << a << endl;cout << "b = " << b << endl;cout << "c = " << c << endl;system("pause");return 0;
}

当我们直接去初始化的时候,编译器是会给我们直接报错的

所以在运用引用的时候一定要先进行初始化,然后再使用
再使用的同时,赋值不是改变它的朝向,而是改变它指向的变量的值

三,  引用做函数的参数

作用:函数传参时,可以利用引用的技术让形参修饰实参

优点:可以简化指针修改实参

示例代码:

//1. 值传递
void mySwap01(int a, int b) {int temp = a;a = b;b = temp;
}//2. 地址传递
void mySwap02(int* a, int* b) {int temp = *a;*a = *b;*b = temp;
}//3. 引用传递
void mySwap03(int& a, int& b) {int temp = a;a = b;b = temp;
}int main() {int a = 10;int b = 20;mySwap01(a, b);cout << "a:" << a << " b:" << b << endl;mySwap02(&a, &b);cout << "a:" << a << " b:" << b << endl;mySwap03(a, b);cout << "a:" << a << " b:" << b << endl;system("pause");return 0;
}

编译输出:

a:10 b:20
a:20 b:10
a:10 b:20
请按任意键继续. . .

参数的形式就是类似于变量的形式:int& a;

总结:通过引用参数产生的效果同按地址传递是一样的。引用的语法更清楚简单

三,引用用做函数的返回值

作用:引用是可以作为函数的返回值存在的

注意:不要返回局部变量引用

用法:函数调用作为左值

//返回局部变量引用
int& test01() {int a = 10; //局部变量return a;
}//返回静态变量引用
int& test02() {static int a = 20;return a;
}int main() {//不能返回局部变量的引用int& ref = test01();cout << "ref = " << ref << endl;cout << "ref = " << ref << endl;//如果函数做左值,那么必须返回引用int& ref2 = test02();cout << "ref2 = " << ref2 << endl;cout << "ref2 = " << ref2 << endl;test02() = 1000;cout << "ref2 = " << ref2 << endl;cout << "ref2 = " << ref2 << endl;system("pause");return 0;
}

编译器输出:

ref = 10
ref = 0
ref2 = 20
ref2 = 20
ref2 = 1000
ref2 = 1000
请按任意键继续. . .

第一个test01表示的当局部变量这样的生命周期很短的,当我们运用引用的返回值来进行操作的时候,会导致引用最后分配失败

第二个test02表示的是引用是可以充当左值的,就比如我们函数返回值为一个引用,然后我们直接用这个函数名字赋值就是可以把这个值改变

四,  常量引用

作用:常量引用主要用来修饰形参,防止误操作

在函数形参列表中,可以加const修饰形参,防止形参改变实参

示例:

//引用使用的场景,通常用来修饰形参
void showValue(const int& v) {//v += 10;cout << v << endl;
}int main() {//int& ref = 10;  引用本身需要一个合法的内存空间,因此这行错误//加入const就可以了,编译器优化代码,int temp = 10; const int& ref = temp;const int& ref = 10;//ref = 100;  //加入const后不可以修改变量cout << ref << endl;//函数中利用常量引用防止误操作修改实参int a = 10;showValue(a);system("pause");return 0;
}

这里有两个知识点:
1  当我们给一个常量引用赋值一个数值的时候,这个时候编译器会创建一个临时的局部变量存储这个数值,然后这个常量引用会指向这个变量

2  当我们设置了常量引用的时候,指向的值是不可以进行更改的,当我们传参的时候就可以很好的运用这个一个点,对我们的数值进行很好的保护,防止值不会被进行更改

对于第一个知识点,《C++primer plus》有额外的例子进行叙述

当我们去函数传参的时候,传入的是一个表达式的时候,这个时候编译器会创建一个临时的变量去保存这个值,然后这个常量引用会指向这个创建的临时变量
编译器都将生成一个临时匿名变量,并让引用变量指向它。这些临时变量只在函数调用期间存在,此后编译器便可以随意将其删除

除此之外,C++primer  plus还举例了另外一个知识点
3  使用 const使函数能够处理 const和非 const 实参,否则将只能接受非 const数据

void processConst(const int& x) {}  // 能接受const和非const实参
void processNonConst(int& x) {}    // 只能接受非const实参int main() {int a = 10;const int b = 20;processConst(a);  // OK:非const -> const引用processConst(b);  // OK:const -> const引用processNonConst(a);  // OK:非const -> 非const引用processNonConst(b);  // 错误!不能将const转为非const
}

就是当我们传参数的时候const的兼容的更多,但是普通的引用的传参不可以兼容const类型的常量


将引用参数声明为常量数据的引用的理由有三个:
• 使用 const 可以避免无意中修改数据的编程错误
• 使用 const使函数能够处理 const和非 const 实参,否则将只能接受非 const数据
• 使用 const 引用使函数能够正确生成并使用临时变量。 因此,应尽可能将引用形参声明为 const


五   总结:

1  引用的基本概念
引用的基本用法:数据类型&  变量名 = 指向的变量

2  引用的注意事项
(a)  引用在创建的时候就要进行初始化
(b)  引用在初始化之后不可以改变指向

3  引用作为函数的参数与用作返回值
(a)  函数的传参没有指针那么的繁琐,不需要考虑解引用问题,直接使用即可
(b)  函数的返回值为引用的时候,当生存周期较短的时候,不要作为引用
(c)  函数的返回值为引用的时候可以作为左值,引用可以作为左值

4  常量引用
这个知识点主要运用到函数的传参里面
(a)  常量引用指向的值是不可以根据引用进行修改的,那么就可以确保数值的安全性
(b)  当没有明确的变量存储值,然而这个值却用常量引用进行指向的话,编译器会自己创建一个临时的变量
(c)  当传参数的时候const的兼容性会更好

http://www.dtcms.com/a/325155.html

相关文章:

  • 一款轻量、免费、无广告,强大的演示工具,支持屏幕放大、涂鸦、截图、录屏
  • PostgreSQL因为A/B switch以及group表过多导致WAL full的情况讨论
  • 托福单词词组积累 2025-08-10
  • 大模型 MCP服务案例详细讲解
  • 线程池的核心线程数与最大线程数怎么设置
  • NVIDIA Jetson AGX Orin 全景解析——边缘计算的高性能选择
  • 攻击实验(ARP欺骗、MAC洪范、TCP SYN Flood攻击、DNS欺骗、DHCP饿死)
  • VGG改进(1):基于Global Attention模块的详解与实战
  • RL代码实践 02——策略迭代
  • ai生成完成后语音通知
  • Starlink卫星终端对星策略是终端自主执行的还是网管中心调度的?
  • 如何部署图床系统 完整教程
  • python魔法属性__module__与__class__介绍
  • 学习numpy详解
  • Shell脚本-其他变量定义
  • 全面了解机器语言之kmeans
  • Redis缓存穿透、缓存击穿、缓存雪崩
  • Mock与Stub
  • 组合期权:水平价差
  • day29 消息队列
  • CST支持对哪些模型进行特征模仿真?分别有哪些用于特征模分析的求解器?
  • 信号处理函数中调用printf时,遇到中断为什么容易导致缓冲区损坏?
  • 介绍一下线程的生命周期及状态?
  • 化工设备健康管理解决方案:基于多物理场监测的智能化技术实现
  • 【系统分析师】软件需求工程——第11章学习笔记(上)
  • 堆(Java实现)
  • 大数据架构演变之路
  • [激光原理与应用-222]:机械 - 3D设计与2D设计的异同比较
  • 赋值运算符指南
  • GoBy 工具安装 | Windows 操作系统安装 GoBy