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 }

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

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。