程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> c++引用學習,引用學習

c++引用學習,引用學習

編輯: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;//引用的本質就是指針 結果為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 }

//如果不是左值,手動先拷貝到內存實體,才能引用
//我們無需拷貝,右值引用,編譯器會自動幫我們拷貝到內存/

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved