C++ 黑马 引用

发布于:2025-08-14 ⋅ 阅读:(17) ⋅ 点赞:(0)

 一,  引用的基本概念

前言:由于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的兼容性会更好


网站公告

今日签到

点亮在社区的每一天
去签到