c++引用学习
0x01:简单的引用
c语言中没有引用,c++有引用,简化编程
引用的本质就是指针,给已经存在的变量起一个别名,sizeof求大小访问的是引用的变量
引用必须一开始就初始化,一旦初始化,赋值修改将无效;
int num = 10;
int & rnum (num);//变量引用用括号好初始化
1.cpp:
1 void main() 2 { 3 double db(10.9); 4 double & rdb(db);//引用必须一开始初始化 5 double dbone(10.8); 6 rdb = dbone;//引用一旦初始化,代码可以编译,赋值修改无效, 7 rdb = 8.9; 8 cout << "db=" << db << " dbone=" << dbone << endl; 9 cout << "dbsize=" << sizeof(db) << " rdbsize=" << sizeof(rdb) << endl; 10 cin.get(); 11 }
1.cpp运行结果:
2.cpp:
1 struct MyStruct 2 { 3 void print() 4 { 5 printf("hello world"); 6 } 7 }; 8 struct MyStructM 9 { 10 char & ch1;//引用的本质是一个地址 11 }; 12 13 void main() 14 { 15 cout << sizeof(MyStructM) << endl;//引用的本质就是指针 结果为4 16 cout << sizeof(MyStruct) << endl;//结果是1 表示存在 17 //结构体大小,空结构体一个字节,表示存在 18 //sizeof求结构体,不计入代码区的内容 19 cin.get(); 20 }
引用的声明方法:类型标识符 &引用名=目标变量名;
1 double db(10.9); 2 double & rdb(db);//类型标识符 &引用名=目标变量名 3 cout << &db << &rdb << endl;//取地址,没有类型说明符是取地址
1 double db1 = 10.9; 2 double db2 = 9.8; 3 double * p(&db1);//定义指针初始化 4 5 double * (&rp)(p);//定义引用的指针,用指针初始化 6 7 double * (&rrp)(rp);//引用可以用另外一个引用初始化 8
引用可以用另一个引用初始化
0x02:高级引用
引用一个数组:
1 //int a 2 //int & ra; 3 //1,挖掉变量名,2,加上&,3 起别名 4 int a[5] = { 1, 2, 3, 4, 5 };//栈上 5 int(&ra)[5] (a);//引用数组 6 int *p = new int[5]{6, 7, 8, 9, 10};//堆上 7 int * (&rp)(p);//引用堆,引用指针就可以 8
1 int *p[5] = { &a[0], &a[1], &a[2], &a[3], &a[4] }; 2 3 int * (&rp)[5](p);//第一挖掉数组名,第二(& +别名)
任何数组类型的引用:
1 void main() 2 { 3 int a[3][3] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } 4 }; 5 6 int *p[3][3] = { &a[0][0], &a[0][1], &a[0][2], 7 &a[1][0], &a[1][1], &a[1][2], 8 &a[2][0], &a[2][1], &a[2][2] }; 9 10 //int * (&rp)[3][3](p); 11 //任何数组类型的引用 12 //第一挖掉变量名 13 //第二加上() 14 //第三加上& 15 //第四加上引用变量名 16 int * (&rp)[3][3](p); 17 18 for (int i = 0; i < 3; i++) 19 { 20 for (int j = 0; j < 3; j++) 21 { 22 cout << (void *)rp[i][j] << " " << *rp[i][j] << endl; 23 } 24 } 25 cin.get(); 26 }
引用可以突破副本机制:
1 double db1 = 10.9; 2 double db2 = 9.8; 3 4 void change(double * & p)//突破副本机制,形参,传引用,传地址 5 { 6 p = &db2; 7 } 8 9 10 void main() 11 { 12 double * p(&db1);//定义指针初始化 13 double * (&rp)(p); 14 change(rp);//实际参数传引用形式参数不是引用不能改变成功 15 cout << *p << endl;//结果为9.8 16 17 cin.get(); 18 }
0x03:超猥琐的引用
函数指针的引用:
1 void print(char *str) 2 { 3 cout << str << endl; 4 } 5 6 void main() 7 { 8 void (*p)(char *str)(print); 9 p("hello world"); 10 11 void(* &rp)(char *str)(p);//函数指针的引用 12 cin.get(); 13 }
引用结构体数组:
1 struct MyStruct 2 { 3 int a; 4 int & ra; 5 6 }; 7 8 void main() 9 { 10 int num[3]{1, 2, 3};//初始化数组 11 MyStruct st[3]{{ 10, num[0] }, { 20, num[1] }, { 30, num[2] }};//初始化结构体数组 12 MyStruct * p = new MyStruct[3]{{ 10, num[0] }, { 20, num[1] }, { 30, num[2] }};//堆上 13 14 MyStruct *(&rp)(p);//引用结构体指针 15 16 MyStruct (& rst)[3](st);//引用结构体数组 17 for (int i = 0; i < 3;i++) 18 { 19 cout << rst[i].a << " " << rst[i].ra << endl; 20 21 } 22 for (int i = 0; i < 3; i++) 23 { 24 cout << rp[i].a << " " << rp[i].ra << endl; 25 26 } 27 cin.get(); 28 }
引用函数指针数组:
1 int add(int a, int b) 2 { 3 return a + b; 4 } 5 int sub(int a, int b) 6 { 7 return a - b; 8 } 9 int mul(int a, int b) 10 { 11 return a * b; 12 } 13 int divv(int a, int b) 14 { 15 return a / b; 16 } 17 18 void mainY() 19 { 20 //函数指针数组int(*p[4])(int, int); 21 int(*p[4])(int, int){ add, sub, mul, divv }; 22 23 int(*(&rp)[4])(int, int)(p);//引用函数指针数组 24 for (int i = 0; i < 4;i++)//下标循环 25 { 26 cout << rp[i](100, 10) << endl; 27 } 28 for (int(**pp)(int, int) = p; pp < p + 4; pp++)//指针循环 29 { 30 int(** &rpp)(int, int)(pp);//引用二级函数指针 31 cout << (*rpp)(100, 10) << endl; 32 33 } 34 cin.get(); 35 36 }
0x04:右值引用
C++11,引用右值
//如果不是左值,手动先拷贝到内存实体,才能引用
//我们无需拷贝,右值引用,编译器会自动帮我们拷贝到内存/
1 void print(int && rint)//右值引用,一旦引用常住内存,编译器自己维护 2 { 3 cout << rint << endl; 4 cout << (void*)&rint << endl; 5 cout << "\n\n"; 6 } 7 8 9 void main() 10 { 11 int x = 30; 12 print(x + 1); 13 14 cout << "\n\n"; 15 print(x + 2); 16 17 cout << "\n\n"; 18 print(x + 3); 19 20 cout << "\n\n"; 21 print(x + 4); 22 cin.get(); 23 24 }
1 void main() 2 { 3 int x = 3; 4 print(x + 1); 5 int && rint(x + 3);//&&引用没有内存实体的临时变量 6 cout << rint << endl; 7 cout << "\n\n"; 8 9 cout << rint << endl; 10 cout << (void*)&rint << endl; 11 cin.get(); 12 }
//如果不是左值,手动先拷贝到内存实体,才能引用
//我们无需拷贝,右值引用,编译器会自动帮我们拷贝到内存/
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。