四、引用
#define _CRT_SECURE_NO_WARNINGS 1 #include<iostream> using namespace std; // 1. 引用的基本语法 type &别名 = 原名 void test01() { int a = 10; int &b = a; b = 20; cout << "a = " << a << endl; // a = 20 cout << "b = " << b << endl; // b = 20 }
void test02() { // int &a; // 报错, 引用必须初始化 int b = 10; int &c = b; int d = 20; // c = d; // 不会报错, 这里是赋值操作,不再是引用a了,所以引用之后不能重新引用,输出的结果是a,b,c == 20 }
void test03() { int arr[10]; int i = 0; for (i = 0; i < 10; i++) { arr[i] = i; } // 给数组起别名 // 方式一 int(&pArr)[10] = arr; // 10 不能省略 for (i = 0; i < 10; i++) { cout << pArr[i] << " "; // 0 1 2 3 4 5 6 7 8 9 } cout << endl; // 方式二 typedef int ARRAYREF[10]; // 一个具有是个元素的 int 类型的数组 ARRAYREF &pArr2 = arr; for (i = 0; i < 10; i++) { cout << pArr2[i] << " "; // 0 1 2 3 4 5 6 7 8 9 } }
四、函数参数的引用
// 值传递 void test04(int x, int y) { int tmp = x; x = y; y = tmp; } // 地址传递 void test05(int* x, int* y) { int tmp; tmp = *x; *x = *y; *y = tmp; } int main() { int a = 10; int b = 20; test04(a, b); // 值传递 cout << "a = " << a << endl; // a = 10 cout << "b = " << b << endl; // b = 20 test05(&a, &b); // 地址传递 cout << "a = " << a << endl; // a = 20 cout << "b = " << b << endl; // b = 10 return EXIT_SUCCESS; }
void test06(int &x, int &y) { int tmp; tmp = x; x = y; y = tmp; } int main() { int a = 10; int b = 20; test06(a, b); cout << "a = " << a << endl; // a = 20 cout << "b = " << b << endl; // b = 10 return EXIT_SUCCESS; }
#define _CRT_SECURE_NO_WARNINGS 1 #include<iostream> using namespace std; int& doWork() { int a = 10; return a; } int& doWork2() { static int b = 10; return b; } void test() { int &ret1 = doWork(); // 引用不能引用局部变量的引用 int &ret2 = doWork2(); // 函数的返回值是引用,那么函数的调用可以作为左值 cout << "ret1 = " << ret1 << endl; // ret1 = 10 局部变量调用之后就被销毁了,这次是对的是编译器的优化所致,后面就不会对了 cout << "ret1 = " << ret1 << endl; // 乱码 cout << "ret1 = " << ret1 << endl; // 乱码 cout << "ret1 = " << ret1 << endl; // 乱码 cout << "ret2 = " << ret2 << endl; // ret2 = 10 cout << "ret2 = " << ret2 << endl; // ret2 = 10 cout << "ret2 = " << ret2 << endl; // ret2 = 10 } int main() { test(); return EXIT_SUCCESS; }
1. 必须初始化
2. 引用之后不能重新引用
3. 引用必须引用一块合法的内存空间 // int &a = 10; 错误
4. 引用不能引用局部变量的引用,如果函数的返回值是引用,那么函数的调用可以作为左值
引用的本质在C++内部实现是一个指针常量.
C++编译器在编译过程中使用指针作为引用的内部实现,因此医用所占用的空间大小与指针相同,只是这个过程是编译器内部实现,用户看不见。#define _CRT_SECURE_NO_WARNINGS 1 #include<iostream> using namespace std; void testFun(int &ref) { ref = 100; // ref 是引用, 转换为 *ref = 100 } int main() { int a = 10; int &aRef = a; // 自动转换为 int *aRef = &a; 这也能说明引用为什么要初始化的原因 aRef = 20; // 内部发现 aRef是引用,自动帮我们转换为 *aRef = 20; cout << "a = " << a << endl; cout << "aRef = " << aRef << endl; testFun(a); return EXIT_SUCCESS; }
#define _CRT_SECURE_NO_WARNINGS 1 #include<iostream> using namespace std; struct Person { int age; }; void allocMemory(Person ** p) // **p 是具体的Persoin对象, *p是对象的指针, p是指针的指针 { *p = (Person *)malloc(sizeof(Person)); (*p)->age = 20; } void test01() { Person *p = NULL; allocMemory(&p); cout << "p的年龄 " << p->age << endl; // p的年龄 20 } // 利用指针引用开辟空间 void allocMemoryByRef(Person* &p) { p = (Person*)malloc(sizeof(Person)); p->age = 20; } void test02() { Person *p = NULL; allocMemoryByRef(p); cout << "p的年龄 " << p->age << endl; // p的年龄 20 } int main() { test01(); test02(); return EXIT_SUCCESS; }
#define _CRT_SECURE_NO_WARNINGS 1 #include<iostream> using namespace std; void test01() { const int &ref = 10; // 加入 const后, 编译器处理方式为 int tmp = 10; const int &ref = tmp; // ref = 20 不能这样改制, 开辟了内存,用指针修改值 int *p = (int *)&ref; *p = 20; cout << "ref = " << ref << endl; // ref = 20 cout << "*p = " << *p << endl; // *p = 20 } int main() { test01(); return EXIT_SUCCESS; }