1、变量名
变量名实质上是一段连续存储空间的别名,是一个标号(门牌号);
通过变量来申请并命名内存空间;
通过变量的名字可以使用内存空间。
2、引用的概念
变量名,本身是一段内存的引用,即别名(alias)。引用可以看作一个已定义变量的别名。
引用的语法:Type & name = var;
用法如下:
1 #include2 using namespace std; 3 4 int main(void) 5 { 6 int a = 10;//C编译器分配4个字节内存,a内存空间的别名 7 int &b = a;//b就是a的别名 8 9 a = 11; 10 { 11 int *p = &a; 12 *p = 12; 13 cout << a << endl;//12 14 } 15 b = 14; 16 cout << "a=" << a << ",b=" << b << endl;//a=14,b=14 17 return 0; 18 }
3、规则
(1)引用没用定义,是一种关系型声明。声明它和原有某一变量(实体)的关系。故类型与原类型保持一致,且不分配内存,与被引用的变量有相同的地址。
(2)声明的时候必须初始化,一经声明,不可更改。
(3)可对引用,再次引用,多次引用的结果是某一变量具有多个别名。
(4)&符号前有数据类型时是引用,其它皆为地址。
1 #include2 using namespace std; 3 4 int main(void) 5 { 6 int a,b; 7 int &r = a; 8 int &r = b;//error,不可更改原有的引用关系——规则(2) 9 float &rr = b;//error,引用类型不匹配——规则(1) 10 cout <<"&r="<< &r << ",&a=" << &a << endl;//变量与引用具有相同的地址——规则(1) 11 int &ra = r;//可对引用再次引用,表示a变量有两个别名,分别是r和ra——规则(3) 12 13 return 0; 14 }
4、引用作为函数参数
普通引用在声明时必须用其它的变量进行初始化,引用作为函数参数声明时不进行初始化。
1 #include2 using namespace std; 3 4 struct Teacher 5 { 6 char name[64]; 7 int age; 8 }; 9 void printfT(Teacher *pT) 10 { 11 cout << pT->age << endl; 12 } 13 14 void printfT2(Teacher &pT)//pT是t1的别名,相当于修改了t1 15 { 16 pT.age = 33; 17 cout << pT.age << endl; 18 } 19 20 void printfT3(Teacher pT)//pT和t1是两个不同的变量 21 { 22 cout << pT.age << endl; 23 pT.age = 45;//只会修改pT变量,不会修改t1变量 24 } 25 26 int main(void) 27 { 28 Teacher t1; 29 t1.age = 35; 30 31 printfT(&t1);//35 32 33 printfT2(t1);//33,pT是t1的别名 34 printf("t1.age:%d\n", t1.age);//33 35 36 printfT3(t1);//33,pT是形参,t1拷贝一份数据给pT 37 printf("t1.age:%d\n", t1.age);//33 38 39 return 0; 40 }
5、引用的意义
(1)引用作为其它变量的别名而存在,因此在一些场合可以代替指针;
(2)引用相对于指针来说具有更好的可读性和实用性。
c++中引入引用后,可以用引用解决的问题避免用指针来解决。
1 #include2 using namespace std; 3 4 struct student 5 { 6 int age; 7 char name[64]; 8 }; 9 void swap1(int *a, int *b) 10 { 11 int temp; 12 temp = *a; 13 *a = *b; 14 *b = temp; 15 } 16 17 void swap2(int &a, int &b) 18 { 19 int temp; 20 temp = a; 21 a = b; 22 b = temp; 23 } 24 25 void printS1(struct student s)//子拷贝方式:student s=s1;结构体整个值拷贝的动作 26 { 27 cout << s.age << " " << s.name << endl; 28 } 29 30 void printS2(struct student *sp)//指针方式 31 { 32 cout << sp->age << " " << sp->name << endl; 33 } 34 35 void printS3(struct student &sp)//引用方式:student &s=s1; 36 { 37 cout << sp.age << " " << sp.name << endl; 38 } 39 40 int main(void) 41 { 42 int a = 10; 43 int b = 20; 44 swap1(&a, &b); 45 cout << "a=" << a << ",b=" << b << endl;//a=20,b=10 46 47 int c = 100; 48 int d = 200; 49 swap2(c, d); 50 cout << "c=" << c << ",d=" << d << endl;//c=200,d=100 51 52 student s1 = { 10,"zhang3" }; 53 printS1(s1);//10 zhang3 54 printS2(&s1);//10 zhang3 55 printS3(s1);//10 zhang3 56 return 0; 57 }
6、引用的本质
引用做参数传递时,编译器会替我们将实参取地址给引用,即:int &a = main :: &b;//a是b的引用;