Loading... ## 引用的基本用法 <div class="tip inlineBlock success"> 引用的本质是对变量取别名 </div> <div class="tip inlineBlock share"> 引用是C++对C的重要扩充。在C++中指针的作用基本都是一样的,但是C++增加了另外一种给函数传递地址的途径,这就是按引用传递(pass-by-reference),它也存在于其他一些编程语言中。并不是C++的发明。 </div> 变量名实质上是一段连续内存空间的别名,是一个标号(门牌号) 程序中通过变量来申请并命名内存空间 通过变量名名字可以使用内存空间 **对一段连续的内存空间只能取一个别名吗?** C++中新增了引用的概念,引用可以作为一个已定义变量的别名。 基本语法: <div class="tip inlineBlock info"> Type& ref = val; 原类型名 &别名=旧名 </div> <div class="tip inlineBlock success"> 引用在等号左边表示引用,在等号右边表示取地址符。 </div> 注意事项: 1. &在此不是取地址运算符,而是起表示作用。 2. 类型识符是指目标变量的类型 3. 必须在声明引用变量时进行初始化 4. 引用初始化后不能改变 5. 不能有NULL引用。必须确保应用时和一块合法的储存单元关联 6. 可以建立对数组的引用 ```C++ #include <iostream> using namespace std; int main(void) { int a = 10; int c = 1; int& b = a; //引用一旦初始化之后,不能改变引用的表示 b = 1000; //b = c;代表吧c的值赋值给b,不是给b取别名 cout << "a = " << a << endl; return 0; } return 0; } ``` ![](https://blog.fivk.cn/usr/uploads/2021/04/2848061520.png) 数组的引用: ```C++ #include <iostream> using namespace std; int main(void) { int a[5] = { 1,2,3,4,5 }; int(&arr)[5] = a;//给a数组取别名为arr for (int i = 0; i < 5; i++) { cout << arr[i] << " "; } cout << endl; return 0; } ``` ![](https://blog.fivk.cn/usr/uploads/2021/04/1991596349.png) ## 函数中的引用 最常见看见引用的地方是在函数参数和返回值中。当引用被用作函数参数时,在函数内部对任何引用的修改,将对还函数外的参数产生改变。当然,可以通过传递一个指针来做相同的事情,但引用具有更清晰的语法。如果从函数中返回一个引用,必须像从函数中返回一个指针一样对待。当函数返回值时,引用关连的内存一定要存在。 * 牛刀小试: ```C++ #include <iostream> using namespace std; void swap(int& x, int& y) { x ^= y; y ^= x; x ^= y; //如果这里看不懂,在Fivk博客搜索 "异或交换变量" } int main(void) { int a = 5; int b = 6; swap(a, b); cout << "a = " << a << endl << "b = " << b << endl; return 0; } ``` ![](https://blog.fivk.cn/usr/uploads/2021/04/161249393.png) * 我们试试对指针引用: Fivk和fivk两个函数都是一样的。 ```C++ #include <iostream> using namespace std; void fivk(int** p) { //常规二级指针 *p = (int*)calloc(5, sizeof(int)); } void Fivk(int* &p) // == int* (&a) = p { //int* 是类型 //p是别名 p = (int*)calloc(5, sizeof(int)); } int main(void) { int *a = NULL; fivk(&a); Fivk(a); return 0; } ``` * 引用作为返回值: 返回的引用是作为左值。不能返回局部变量的引用,可以返回静态变量的引用。 <div class="tip inlineBlock success"> 能不能返回一个变量的引用,看这个变量的空间是否被释放了。 </div> ```C++ #include <iostream> using namespace std; int& fivk_cn() { static int b = 100; int a = 10; //return a;//error 不能返回局部变量的引用 return b;//可以返回静态的变量引用 } int main(void) { int *a = NULL; fivk_cn() = 1000; return 0; } ``` ## 引用的本质 引用的本质在C++内部实现是一个指针常量。 <div class="tip inlineBlock success"> Type& ref = val;//Type* const ref = &val; </div> C++编译器在编译过程中使用常量指针作为引用内部实现,因此引用所占的空间大小与指针相同,这是这个过程是编译器内部实现,用户不可见。 ```C++ //发现是引用,转换为 int * const ref = &a; void testFunc(int& ref) { ref = 100; //ref是引用,转换为*ref = 100; } int main() { int a = 10; int& aRef = a;//自动转换为 int * const aRef = &a;这也能说明引用为什么必须初始化 aRef = 20;//内部发现aRef是引用,自动帮我们转换为 *aRef = 20; cout << "a = " << a << endl; cout << "aRef = " << aRef << endl; testFunc(a); return 0; } ``` <div class="tip inlineBlock success"> 因为引用的指针加上了 const 修饰,所以应用后不能改变指针的指向,因为它是一个指针常量。 </div> ## 指针引用&数组引用&常量引用 套用引用公式:Type &p =q; * 指针引用 ```C++ void fivk(int*& ref) { static int a; ref = &a; } int main() { int* p = NULL; fivk(p); return 0; } ``` * 数组引用 ```C++ void Test(int (&array)[5]) { cout << "size:" << sizeof(array) << endl; for (int i = 0; i < sizeof(array)/4; i++) { cout << array[i] << " "; } } int main() { int array[5] = {1,2,3,4,5}; Test(array); return 0; } ``` * 常量的引用 > 常量引用的定义格式: > > const Type & ref = val; 常量引用注意: 1. 字面量不能赋给引用,但是可以赋给const引用 2. const修饰的引用,不能修改。 ```C++ #include<iostream> using namespace std; int main(void) { int a = 10; const int& b = a; //const 修饰的是引用& 不能通过引用去修改引用的这块空间的内容 int& c = 100;//error 不能引用常量 //但是 const int& d = 100;//这样是可以的。 //实质:int tmp=100; const int & d=tmp; return 0; } ``` 最后修改:2021 年 04 月 10 日 © 禁止转载 打赏 赞赏作者 支付宝微信 赞 如果觉得我的文章对你有用,请随意赞赏