首页 > 代码库 > c++引用学习

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;//引用的本质就是指针 结果为416     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 a2     //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.816 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 }

//如果不是左值,手动先拷贝到内存实体,才能引用
//我们无需拷贝,右值引用,编译器会自动帮我们拷贝到内存/

c++引用学习