概念
对变量取别名
普通引用必须要初始化
#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);
}