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運行結果:
dbone的值沒有改變,//引用必須一開始就初始化,一旦初始化,賦值修改將無效;
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 }