C++引用

引用变量是C++新增的复合类型。
引用是已定义的变量的别名。
引用的主要用途是用作函数的形参和返回值。
声明/创建引用的语法:数据类型 &引用名=原变量名

实际上这个引用就是变量的别名

#include<iostream>
#include<algorithm>
#include<cstring> 
using namespace std;
int main() {
	int a = 3;
	int& ra = a;
	cout << "a的地址是:" << &a << ",a的值是:" << a << endl;
	cout << "ra的地址是:" << &ra << ",ra的值是:" << ra << endl;
	ra = 8;
	cout << "a的地址是:" << &a << ",a的值是:" << a << endl;
	cout << "ra的地址是:" << &ra << ",ra的值是:" << ra << endl;

	return 0;
}

在这里插入图片描述注意:

  • 引用的数据类型要与原变量名的数据类型相同。
  • 引用名和原变量名可以互换,它们值和内存单元是相同的。
  • 必须在声明引用的时候初始化,初始化后不可改变。
  • C和C++用&符号来指示/取变量的地址,C++给&符号赋予了另一种含义。

我们看这个代码:

#include<iostream>
#include<algorithm>
#include<cstring> 
using namespace std;
int main() {
	int a = 3;
	int& ra = a;
	cout << "a的地址是:" << &a << ",a的值是:" << a << endl;
	cout << "ra的地址是:" << &ra << ",ra的值是:" << ra << endl;
	int b = 5;
	ra = b;//把b的值赋给ra
	cout << "a的地址是:" << &a << ",a的值是:" << a << endl;
	cout << "ra的地址是:" << &ra << ",ra的值是:" << ra << endl;

	return 0;
}

运行结果是:

注意看这代码的意思是b的值赋给ra和a,而不是ra又变成b的引用。

引用的本质

引用时指针常量的伪装
引用是编译器提供的一个有用且安全的工具,去除了指针的一些缺点,禁止了部分不安全的操作。
变量是什么?变量就是一个在程序执行过程中可以改变的量。
换一个角度,变量是一块内存区域的名字,它代表了这块内存区域,当我们对变量进行修改的时候,会引起内存区域中内容的改变。

引用用于函数的参数

把函数的形参声明为引用,调用函数的时候,形参将成为实参的别名。
这种方法也叫按引用传递或传引用。(传值、传地址、传引用只是说法不同,其实都是传值。)
引用的本质是指针,传递的是变量的地址在函数中,修改形参会影响实参。

  • 传引用的代码更简洁。’
  • 传引用不必使用二级指针。’
  • 引用的属性和特别之处。‘

我们只需要把形参改为引用就行。

#include<iostream>
#include<algorithm>
#include<cstring> 
using namespace std;
void func3(int& no, string& str) {//把形参改为引用就行
	no = 8;
	str = "我有一只小小鸟";
	cout << "亲爱的" << no << "号:" << str << endl;
}
int main() {
	int bh = 3;
	string message = "我是一只傻傻鸟。";
	cout << "亲爱的" << bh << "号:" << message << endl;
	func3(bh, message);
	cout << "亲爱的" << bh << "号:" << message << endl;
	return 0;
}

引用的形参和const的用途

如果引用的数据对象类型不匹配,当引用位const时,C++将创建临时变量,让引用指向临时变量。
什么时候将创建临时变量呢?

  • 引用是const.
  • 数据对象的类型正确,但不是左值
  • 数据对象的类型不正确,但是可以转化位正确的类型

例如:int &ra=8会报错,但是const int& ra=8则不会报错。

#include<iostream>
#include<algorithm>
#include<cstring> 
using namespace std;
void func3(const int& no, const string& str) {
	cout << "亲爱的" << no << "号:" << str << endl;
}
int main() {
	func3(3, "我是一只小小鸟");
	func3('X', "我是一只小小鸟");//这样也可以
	return 0;
}

结论:如果函数的实参不是左值或与const引用形参的类型不匹配,那么C++将创建正确类型的匿名变量,将实参的值传递给匿名变量,并让形参来引用该变量。

将引用形参声明为const的理由有三个:

  • 使用const可以避免无意中修改数据的编程错误。
  • 使用const使函数能够处理const和非const实参,否则将只能接受非const实参。
  • 使用const,函数能正确生成并使用临时变量。

左值是可以被引用的数据对象,可以通过地址访问它们,例如:变量、数组元素用和解引用的指针。

引用用于函数的返回值

传统的函数返回机制和值传递类似。
函数的返回值被拷贝到一个临时位置(寄存器或栈),然后调用者程序再使用这个值。

double m=sqrt(36);//sqrt()是求平方根函数。

sqrt(36)的返回值6被拷贝到临时的位置,然后赋值给m。

cout << sqrt(25);

sqrt(25)的返回值5被拷贝到临时的位置,然后传递给cout。
如果返回的是一个结构体,将把整个结构体拷贝到临时的位置
如果返回引用不会拷贝内存

语法:
返回值的数据类型&函数名(形参列表);
注意:

  • 如果返回局部变量的引用,其本质是野指针。
  • 可以返回函数的引用参数、类的成员、全局变量、静态变量。
  • 返回引用的函数是被引用的变量的别名,将const用于引用的返回类型。
    例如:
#include<iostream>
#include<algorithm>
#include<cstring> 
using namespace std;
int func1() {//返回的是值
	int i = 2;
	return i;
}
int& func2() {//返回的是引用
	int i = 3;
	return i;
}
int main() {
	int a = func1();cout << "a=" << a << endl;
	int& b = func2();cout << "b=" << b << endl;

	return 0;
}

我们在看一个例子:

#include<iostream>
#include<algorithm>
#include<cstring> 
using namespace std;
int& func2(int& ra) {
	ra++;
	cout << "ra的地址是:" << &ra << "ra=" << ra << endl;

	return ra;
}
int main() {
	int a = 2;
	int& b = func2(a);
	cout << "a的地址是:" << &a << "a=" << a << endl;
	cout << "b的地址是:" << &b << "a=" << b << endl;


	return 0;
}

在这里插入图片描述
这里的地址都是一个,ra,a,b的地址都是一个。

各种形参的使用场景

传值、传地址和传引用的指导原则《C++Primer Plus》
1) 如果不需要在函数中修改实参:

  • 如果实参很小,如内置数据类型或小型结构体,则按值传递。
  • 如果实参是数组,则使用const 指针,因为这是唯一的选择(没有为数组建立引用的说法)。
  • 如果实参是较大的结构,则使用const指针或const 引用。
  • 数据实参是类,则使用const引用,传递类的标准方式是按引用传递。

2) 如果需要在函数中修改实参

  • 如果实参是内置数据类型,则使用指针。只要看到func(&x)的调用,表示函数将修改x
  • 如果实参是数组,则只能使用指针。
  • 如果实参是结构体,则使用指针或引用。
  • 如果实参是类,则使用引用。
    当然,这只是一些指导原则,很可能有充分的理由做出其他的选择。
    例如:对于基本类型,cin使用引用,因此可以使用cin>>a,而不是cin> >&a
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值