15 引用

概念

对变量取别名

普通引用必须要初始化

#include<iostream>
using namespace std;

int main() {
	int a = 10;
	int& b = a;
	cout << "b: " << b << endl; // 10
	cout << "a: " << a << endl; // 10
	a = 200;
	cout << "b: " << b << endl; // 200
	cout << "a: " << a << endl; // 200
	b = 100;
	cout << "b: " << b << endl; // 100
	cout << "a: " << a << endl; // 100
}

引用做函数参数

#include<iostream>
using namespace std;

// 结束后出栈释放,不能实现功能
void myswap(int a, int b) {
	int c = 0;
	c = a;
	a = b;
	b = c;
}
// 指针实现功能
void myswap2(int* a, int* b) {
	int c = 0;
	c = *a;
	*a = *b;
	*b = c;
}
// 引用实现功能,做函数参数时不用初始化
void myswap3(int& a, int& b) {
	int c = 0;
	c = a;
	a = b;
	b = c;
}

void main() {
	int x, y;
	x = 10;
	y = 20;
	cout << "x:" << x << "  y:  " << y << endl;
	myswap3(x, y);
	cout << "func swap:	";
	cout << "x:" << x << "  y:" << y << endl;
}

复杂数据类型引用

struct Teacher{
    char name[64];
    int age;
};

void printfT(Teacher *pT){
    cout << pT->age <<endl;
}

void printfT2(Teacher &pT){
    cout << pT.age << endl;
} 

void printfT3(Teacher pT){
    cout << pT.age << endl;
    pT.age = 45;
}

void main(){
    Teacher t1;
    t1.age = 35;
    printfT(&t1);
    
    printfT2(t1); // pT 是 t1 的别名
    
    printfT3(t1); // pT 是形参,t1拷贝数据给pT // pT = t1
	cout << t1.age << endl; // 35 不改变
}

引用的意义

替代指针,更好地可读性

本质

单独定义时,必须初始化赋值,很像常量

void main() {
	int a = 10;
	int& b = a;
	cout << "a: " << a << "\t&a: " << &a << "\t";
	cout << "b: " << b << "\t&b: " << &b;
}
// 两个地址值一样

很像指针,占内存

struct Teacher {
	char name[64];	// 64
	int age;	// 4
	int& a;		// 4
	int& b;		// 4
};

void main() {
	cout << sizeof(Teacher) << endl;
}
// 76

引用的本质 c++内部实现常量指针, 内存大小和指针一样

Type* const name

void modifyA(int& a) {
	a = 10;
}

void modifyA2(int* a) {
	*a = 20;
}

void main() {
	int a = 2;
	cout << a << endl;		// 2
	modifyA(a);		
	cout << a << endl;		// 10
	modifyA2(&a);
	cout << a << endl;		// 20
}

间接赋值成立条件

1 2个变量 一个实参 一个形参

2 建立关系,实参取地址传递给形参

3 *p形参去间接修改实参的值

引用只是把后两个条件合在一起

函数返回值是一个引用(引用作左值)

当函数返回值为引用时,若返回栈变量,不能成为其他引用的初始值,不能做左值使用

int getAA1() {
	int a;
	a = 10;
	return a;
}

// 返回 a 的本身 内存空间
int& getAA2() {
	int a;
	a = 10;
	return a;	// 如果返回栈变量,可能有问题
}

int* getAA3() {
	int a;
	a = 10;
	return &a;
}
void main() {
	int a1 = 0;
	int a2 = 0;
	a1 = getAA1();
	a2 = getAA2(); // 10 
	

	cout << "a1: " << a1 << "\na2:" << a2 << "\n";

	int& a3 = getAA2();

	cout << "a3:" << a3 << endl; // (a3)指向的内存空间被析构了,所以可能出现乱码
}

若返回静态变量或全局变量,可以成为其他引用的初始值,既可以作左值,又可以做右值

int j1() {
	static int a = 10;
	a++;
	return a;
}

int& j2() {
	static int a = 10;
	a++;
	return a;
}

void main() {
	int a1 = 10;
	int a2 = 20;

	a1 = j1();
	a2 = j2();

	int& a3 = j2();

	cout << "a1: " << a1 << "\na2:" << a2 << "\n";
	cout << "a3:" << a3 << endl; 
}

函数作为左值

// 返回变量的值
int g1() {
	static int a = 10;
	a++;
	return a;	// 11
}

// 返回变量本身
int& g2() {
	static int a = 10;
	a++;
	cout << a << endl;
	return a;
}

void main() {
	// g1() = 100;
	g2() = 100;	// 引用作为左值,将100赋值给a 输出 11
	g2();	// 输出101

	int c1 = g1();
	int c2 = g2();
	cout << c2 << endl;
}

指针引用

指针修改

struct Teacher {
	char name[64];
	int age;
};

int getTeacher(Teacher** p) {
	Teacher* tmp = nullptr;
	if (p == NULL) {
		return -1;
	}
	tmp = (Teacher*)malloc(sizeof(Teacher));
	if (tmp == nullptr) {
		return -2;
	}
	tmp->age = 33;
	// p是实参的地址,*p间接修改实参的值
	*p = tmp;
}

// 指针引用做函数参数
int getTeacher2(Teacher*& myp) {
	// 给myp赋值 相当于给pT1赋值
	myp = (Teacher*)malloc(sizeof(Teacher));
	if (myp == nullptr) {
		return -1;
	}
	myp->age = 36;
}

void FreeTeacher(Teacher *pT1) {
	if (pT1 == nullptr) {
		return;
	}
	free(pT1);
}

void main() {
	Teacher* pT1 = nullptr;

	// c语言中二级指针
	getTeacher(&pT1);
	cout << pT1->age << endl;

	FreeTeacher(pT1);

	// c++中指针的引用
	getTeacher2(pT1);
	cout << pT1->age << endl;

	FreeTeacher(pT1);
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值