引用
变量名
变量名实质上是一段连续存储空间的别名,是一个标号(门牌号)
通过变量来申请并命名内存空间.
通过变量的名字可以使用存储空间.
引用的概念
变量名,本身是一段内存的引用,即别名(alias). 引用可以看作一个已定义变量的别名。
引用的语法:Type& name = var;
#define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace std; int main() { int a = 10; //c编译器分配4个字节内存, a内存空间的别名 int b = 30; int *p = &a; //&a是取a的地址 *p = 30; p = &b; *p = 20; //b int &re = a; //int & 使用引用数据类型, re就是a的别名 re = 50; //则a = 50 re = b; //此时不是让re成为b的引用 而是把b的值赋值给re re = 50; cout << "a=" << a << endl; cout << "b=" << b << endl; system("Pause"); //阻塞功能 return EXIT_SUCCESS; // 返回正常退出 }
结果:
规则
1 引用没有定义,是一种关系型声明。声明它和原有某一变量(实体)的关 系。故而类型与原类型保持一致,且不分配内存。与被引用的变量有相同的地址。
2 声明的时候必须初始化,一经声明,不可变更。
3 可对引用,再次引用。多次引用的结果,是某一变量具有多个别名。
4 &符号前有数据类型时,是引用。其它皆为取地址
#define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace std; void test() { int a = 10; int b = 20; //int &r; //error 引用一定要初始化, 起别名一个得先有个名 int &r = a; //int &r = b; //error 不可改变原有的引用关系,一经声明,不可变更 int &r2 = r; //可对引用再次引用,表示a变量有两个别名 分别是r 和 r2 float &r3 = a; //error 引用类型不匹配, 变量和引用具有相同地址,类型要与元类型一致 }
引用作为函数参数
struct Person { int age; }; void ChangeVal(int &r) //当我们将引用作为函数传递时,编译器会替我们将实参,区地址给引用 即:int &r = &a (传递过来的实参a自动取地址) //相当于int &r = a { r = 300; //对一个引用操作赋值的时候,编译器替我们隐藏*操作 若: *r = 300 } void ChangeVal2(int* r) //int* r = a 传递实参要加& { } void motify(int *const r ) //int *const r = a {} void AllocatMemory(Person **p) //**p 具体的Person对象 *p对象的指针 p 指针的指针 ??? { *p = (Person*)malloc(sizeof(Person)); (*p)->age = 18; } void test01() { Person* p = NULL; AllocatMemory(&p); cout << "age=" << p->age << endl; } void AllocatMemory2(Person* &p) //利用指针引用开辟空间 { p = (Person*)malloc(sizeof(Person)); p->age = 28; } void test02() { Person* p = NULL; AllocatMemory2(p); cout << "age2=" << p->age << endl; }
普通引用在声明时必须用其它的变量进行初始化,引用作为函数参数声明时不进行初始化。
#define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace std; struct Teacher { char name[64]; int age; }; //pT和t1是两个不同的表里 void printfT(Teacher pT) { pT.age = 20; //只会修改pT变量 不会修改t1变量 cout << "T函数内:"<< pT.age << endl; } void printfT2(Teacher *pT) { pT->age = 24; //利用指针修改变量 } void printfT3(Teacher &pT) //pT是t1的别名,相当于t1 { pT.age = 26; } int main() { Teacher t1; t1.age = 18; printfT(t1); cout << "T:t1.age=" << t1.age << endl; printfT2(&t1); cout << "T2:t1.age=" << t1.age << endl; printfT3(t1); cout << "T3:t1.age=" << t1.age << endl; system("Pause"); //阻塞功能 return EXIT_SUCCESS; // 返回正常退出 }
结果
引用的意义
1)引用作为其它变量的别名而存在,因此在一些场合可以代替指针
2)引用相对于指针来说具有更好的可读性和实用性
#define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace std; void swap2(int a, int b); //无法实现两个数据的交换 void swap3(int *p, int *q); //开辟两个指针空间实现交换 void swap(int &a, int &b) { int tmp; tmp = a; a = b; b = tmp; } int main() { int a = 3, b = 4; swap(a, b); cout << "a=" << a << ", b= " << b << endl; }
const引用
1.如果要对一个常量进行引用,必须是一个const引用
#define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace std; int main() { const int a = 10; int &re = a; //err const int &re2 = a; //ok system("Pause"); //阻塞功能 return EXIT_SUCCESS; // 返回正常退出 }
2.一个普通变量,可以用一个const引用接收,但是原变量可以更改,const引用改变不了
int b = 20; const int &re3 = b; //ok re3 = 30; //err b = 30; //ok cout << "re3=" << re3 << endl; //30