文章目录
- 1.变量的别名
- 2.变量的多个别名
- 3.引用存在的价值
- 4.引用的大小
- 5.从汇编角度看引用
- 6.结构体的引用
- 7.指针的引用
- 8.数组的引用
1.变量的别名
在 C 语言中,使用指针(Pointer)可以间接获取、修改某个变量的值。在 C++ 中,使用引用(Reference)可以起到跟指针类似的功能。
引用相当于是变量的别名,一般用 &
符号表示,基本数据类型、枚举、结构体、类、指针、数组等都可以有引用。
引用必须绑定到变量上去,不能绑定到常量上去。引用指向的类型要相同。
对引用做计算,就是对引用所指向的变量做计算。
在定义的时候就必须初始化,一旦指向了某个变量,就不可以再改变,“从一而终”。
#include
using namespace std;int main() {int age &#61; 10;int height &#61; 20;int &ref &#61; age;ref &#61; 20;ref &#43;&#61; 30;cout << age << endl; ref &#61; height;ref &#61; 11;cout << age << endl; cout << height << endl; return 0;
}
2.变量的多个别名
可以利用引用初始化另一个引用&#xff0c;相当于某个变量的多个别名。
#include
using namespace std;int main() {int age &#61; 10;int& ref &#61; age;int& ref1 &#61; ref;int& ref2 &#61; ref1;ref &#43;&#61; 10;ref1 &#43;&#61; 10;ref2 &#43;&#61; 10;cout << age << endl; return 0;
}
3.引用存在的价值
不存在 “引用的引用”、“指向引用的指针”、“引用数组”。
引用存在的价值之一&#xff1a;比指针更安全、函数返回值可以被赋值。
举例1&#xff1a;通过指针传参交换两个数
#include
using namespace std;void swap(int *v1, int *v2) {int tmp &#61; *v1;*v1 &#61; *v2;*v2 &#61; tmp;
}int main() {int a &#61; 10;int b &#61; 20;swap(&a, &b);cout << "a &#61; " << a << ", b &#61; " << b << endl; return 0;
}
举例2&#xff1a;通过引用传参交换两个数
#include
using namespace std;void swap(int &v1, int &v2) {int tmp &#61; v1;v1 &#61; v2;v2 &#61; tmp;
}int main() {int a &#61; 10;int b &#61; 20;swap(a, b);cout << "a &#61; " << a << ", b &#61; " << b << endl; int c &#61; 2;int d &#61; 3;swap(c, d);cout << "c &#61; " << c << ", d &#61; " << d << endl; return 0;
}
4.引用的大小
一个引用占用一个指针的大小。
举例1&#xff1a;只含一个 int 整数的类对象的大小
#include
using namespace std;struct Student {int age;
};int main() {cout << sizeof(Student) << endl;return 0;
}
举例2&#xff1a;只含一个 int 指针的类对象的大小
#include
using namespace std;struct Student {int *age;
};int main() {cout << sizeof(Student) << endl;return 0;
}
举例3&#xff1a;只含一个 int 引用的类对象的大小
#include
using namespace std;struct Student {int &age;
};int main() {cout << sizeof(Student) << endl;return 0;
}
5.从汇编角度看引用
引用的本质就是指针&#xff0c;只是编译器削弱了它的功能&#xff0c;所以引用就是弱化了的指针。
加断点&#xff0c;按 F5 进入调试&#xff0c;转到反汇编&#xff0c;不勾选“显示符号名”。
举例1&#xff1a;查看 int 指针的汇编代码
#include
using namespace std;int main() {int age &#61; 10;int *p &#61; &age;*p &#61; 30;return 0;
}
举例2&#xff1a;查看 int 引用的汇编代码
#include
using namespace std;int main() {int age &#61; 10;int &ref &#61; age;ref &#61; 30;return 0;
}
对比两图可以发现&#xff0c;ref
本质上就是指针&#xff0c;存储的就是 age
的地址值。
6.结构体的引用
#include
using namespace std;struct Date {int year;int month;int day;
};int main() {Date d &#61; { 2022, 1, 25 };Date& ref &#61; d;ref.year &#61; 2023;cout << d.year << endl; return 0;
}
7.指针的引用
指针是一个存放地址的变量&#xff0c;而指针引用指的是这个指针变量的引用。
#include
using namespace std;int main() {int age &#61; 10;int *p &#61; &age;int *&ref &#61; p;*ref &#61; 30;cout << age << endl; int height &#61; 40;ref &#61; &height;cout << *ref << endl; return 0;
}
在 C&#43;&#43; 中&#xff0c;如果参数不是引用的话&#xff0c;会调用参数对象的拷贝构造函数&#xff0c;所以如果想改变指针所指的对象&#xff08;即想要改变指针里面存的地址&#xff09;&#xff0c;就要使用指针引用。
举例1&#xff1a;指针
#include
using namespace std;struct Point
{int x;int y;
};void change1(Point* pp)
{pp &#61; new Point;pp->x &#61; 4;
}int main()
{Point* p &#61; new Point;p->x &#61; 10;cout << "指针前&#xff1a;" << p->x << endl;change1(p);cout << "指针后&#xff1a;" << p->x << endl;return 0;
}
举例2&#xff1a;指针的引用
#include
using namespace std;struct Point
{int x;int y;
};void change2(Point* &pp)
{pp &#61; new Point;pp->x &#61; 4;
}int main()
{Point* p &#61; new Point;p->x &#61; 10;cout << "指针引用前&#xff1a;" << p->x << endl;change2(p);cout << "指针引用后&#xff1a;" << p->x << endl;return 0;
}
8.数组的引用
举例1&#xff1a;区分指针数组、数组指针、数组的引用
#include
using namespace std;int main() {int array[3] &#61; {1, 2, 3};int *arr1[3] &#61; {array, array, array};int (*arr2)[3] &#61; &array;int (&ref)[3] &#61; array;ref[0] &#61; 10;cout << array[0] << endl; return 0;
}
举例2&#xff1a;引用数组的两种格式
#include
using namespace std;int main() {int arr[] &#61; {1, 2, 3};cout << *(arr &#43; 2) << endl; int (&ref)[3] &#61; arr;cout << ref[2] << endl; int * const &refArr &#61; arr;cout << refArr[2] << endl; return 0;
}