天天看點

int & 到底是個啥?

         感覺自己很廢,很懶。不懂得東西模棱兩可就過去了,廢物,垃圾。現在的知識盲區大了吧!大家敬請鄙視我吧!

         故事是這樣的:

#include<stdio.h>
 
 void change1 (int *a,int *b)
 {
 	int c;
 	c=*a;
 	*a=*b;
 	*b=c;
 }
 
 
  void change2 (int &m,int &n)
 {
 	int c;
 	c=m;
 	m=n;
 	n=c;
 }
 
 
 int main()
 {
 	int a=1;int m=1;
 	int b=2;int n=2;
 	
 	change1(&a,&b);
 	printf("-a-%d--\n",a);
 	printf("-b-%d--\n\n\n",b);
 	
 	change2(&m,&n);                //錯誤,錯誤,錯誤
 	printf("-m-%d--\n",m);
 	printf("-n-%d--\n\n\n",n);
 	return 0;
 }
           

哎,chang2裡面的形參不是需要兩個位址嗎? &m,&n,不是取位址嗎?對啊!我傳入兩個位址,沒毛病啊!這是當初學C語言心中的疑惑,但是我是個廢柴!哦,書上說不用寫&,直接寫m,n就行了。好了我記住了!but!but!but!廢柴是不知道原理是什麼的,隻知道這樣子去用。好了,今天遇到問題報錯了吧!廢柴開始緊張了!

在這裡不得不吐槽教科書,垃圾,就寫一句“注意int &不是取位址,是引用,詳情自主百度”不就交代的很清楚了嗎?害我這個廢柴找了半天答案。垃圾教科書。

這裡引用“落辰衰”大佬的解釋:

1、int;

int是C++關鍵字,表示整型,其大小是32位有符号整型,表示的範圍是-2,147,483,648 到 

2,147,483,647;在聲明和定義變量時使用,它表示的意思是所聲明或所定義的變量為整型變量。

如果其用于函數參數時,其傳遞方向為值傳遞,即隻能将實參的值傳遞給形參,而不能将

形參的值傳遞給實參。

例如:通過這種方式去進行交換兩個數是無法達到目的的。

例子1:

#include<iostream>

using namespace std;            

voidswap1(inta,intb)

{   

     inttmp;   

     tmp = a;    

     a = b;    

     b = tmp;    

 }   

 int main(){   

     inta = 1;    

     intb = 2;    

     swap1(a, b);    

     cout<<"a = "<<a<<endl;   

     cout<<"b = "<<b<<endl;   

     system("pause");   

     return0;   

 }

結果為:a=1

b=2

因為傳遞的方式為值傳遞(單向傳遞);

2、int&;

這裡的&不是取位址符号,而是引用符号,引用是C++對C的一個重要補充。變量的引用就是

變量的别名,講的通俗一點就是另外一個名字,比如:“張三這個人在家裡,老爸老媽叫他

三娃子,那麼這個三娃子就是指張三這個人,如果叫張三去做某事,就是叫三娃子去做某事,

這兩個名字指的是同一個人。”同樣可以了解如果變量b是變量a的引用 那麼無論a,b中任

何一個值改變,另外一個也相應的改變,在聲明一個引用時,必須同時使之初始化,即聲

明它代表哪一個變量。請注意:由于引用不是獨立的變量,編譯系統不給它單獨配置設定存

儲單元,是以在建立引用時隻有聲明沒有定義,隻是聲明它與原有的某一變量的關系。

在聲明一個變量的引用後,在本函數執行期間,該引用一直與其代表的變量相聯系,不能

再作為其他變量的别名。說得簡單點:張三和三娃子是指同一個人,不能李四也叫三娃子,

如果可以這樣,叫三娃子去做什麼,是叫李四呢還是張三呢,這就會亂套了。是以在C++中

一個引用變量隻能對應一個原始的變量,不能對應兩個或多個原始的變量;

下面簡單說明引用:

a)聲明引用時必須指定它代表的是哪一個變量,即對它初始化。

int &a=b;這樣是聲明a是變量b的引用

如果是int &a;這樣就是錯的,沒有指定a代表哪一個變量。

b)引用與其所代表的變量共享同一記憶體單元,系統并不為引用另外配置設定存儲單元;

這個應該好了解;就像前面所說的,張三和三娃子都是同一個人,三娃子隻是張三的别名。

是以,對于 int &a=b;這個例子來說,要輸出a和b 的位址,肯定是相同的。

c)怎樣區分&是引用還是取位址符呢?方法是:判斷&a這樣的形式前是否有類型符即

int &a=b;如果有類型符(int)則是引用,否則是取位址運算符。

d)對引用的初始化,可以是一個變量名,也可以是另一個引用。

換句話說:張三的别名可以是三娃子,三小子……及其他多個别名

而三娃子也可以有其他的别名,比如說:老三,小三等

用程式可以這樣:

int a=1; //這裡是定義一個整形變量

int &b=a;//聲明b是整型變量a的别名

int &c=b;//聲明c是整型引用變量b的别名

int &d=a;//聲明d是整型變量a的别名

e)引用初始化後不能再被重新聲明為另一變量的别名

即三娃子既然是指張三這個人,就不能讓其他人也叫三娃子

即一個别名隻能對應一個原始變量,但是一個原始變量可以有多個别名,而且别名也可以

由自己的别名。

C++中增加引用主要是作為函數參數,進行資料傳遞的功能;

我們知道如果用變量名作為實參,其傳遞方向是單向的,而用引用作為實參其傳遞方向

是雙向的;

也許你會問,在c語言中不是有指針嗎,用指針進行參數傳遞不也是雙向的嗎?其實其

本質上也是值傳遞,隻不過是将變量的位址傳給指針,通過指針擷取變量的值,這樣做

雖能得到結果,但通過指針運算符去通路有關變量,比較麻煩。

下面分析一下使用引用和使用指針變量作為函數形參的不同(以例子1中的swap函數為例):

1、如果使用引用,則不必在swap函數設立指針變量,指針變量要另外開辟記憶體單元,其

内容是位址。而引用不是一個獨立的變量,并不占用記憶體單元

2、在main函數中調用swap函數時實參不必再變量名前加&以表示位址,系統傳遞的是

實參的位址不是實參的值。

3、使用指針變量時,為了表示指針變量所指向的變量,必須使用指針運算符*,而使用

引用時,引用就代表該變量,不必使用指針運算符*;

4、用引用完成的工作,用指針也能完成。但引用比指針的使用直覺、友善,直截了當,

不必“兜圈子”,容易了解。有些過去隻能用指針來處理的問題,現在可以用引用來代替,

進而降低了程式設計的難度。

對引用進一步說明:

1、不能建立void類型的引用。

因為任何實際存在的變量都是屬于非void類型的,void的含義是無類型或空類型,

void隻是在文法上相當于一個類型而已。

2、不能建立引用的數組。

如:char c[6]="hello";

char &rc=c;//錯誤

因為數組名是數組首元素的位址,本身不是一個占有存儲空間的變量。

3、可以将變量的引用的位址賦給一個指針,此時指針指向的是原來的變量。

這句話可以這樣說:将引用變量的位址賦給一個指針,此時指針指向的是引用變量,

相當于指向原來的變量

int a=2;

int &b=a;//這個聲明語句中的&是一個引用

int *p=&b;//這個指針初始化語句中的&是取位址運算符

上面一行等價于 int *p=&a;

但是不能定義指向引用類型的指針變量,不能寫成

int & *p=&a;//企圖定義指向引用類型的指針變量p,錯誤

因為引用不是一種獨立的資料類型,是以不能建立指向引用類型的指針變量。

4、可以建立指針變量的引用如

int i=5;

int *p=&i;

int * &pt=p;//建立指針變量p的引用pt

引用變量pt代表一個int *類型的資料對象(即指針變量)

5、可以用const對引用加以限定,不允許直接改變該引用的值,但是可以改變原

變量的值去改變引用的值;

int i=5;

const int &a=i;

a=3;//錯誤,因為引用a是const int 類型不能直接改變引用的值

但是可以這樣修改:

i=3;

此時輸出i和a都是3

6、可以用常量或表達式對引用進行初始化,但此時必須用const作聲明。

int i=5;

const int &a=i+1;

此時編譯系統是這樣處理的:生成一個臨時變量,用來存放該表達式的值,引用是

該臨時變量的别名、系統将“const int &a=i+1;”轉換為

int temp=i+1;

const int &a=temp;

臨時變量是在内部實作的,使用者不能通路臨時變量;

用這種辦法不僅可以用表達式對引用進行初始化,還可以用不同類型的變量對之

初始化;如

double d=3.1415926;

const int &a=d;

以上等價為:

double d=3.1415926;

int temp=d;

const int &a=temp;

如果在上面不用const則會發生錯誤

double d=3.1415926;

int &a=d;//未加const,錯誤

為什麼?因為如果可以這樣做,那麼修改引用a的值(如a=3.56),則臨時變量temp的值也

變為3.56,即修改了臨時變量temp的值,但不能修改變量d的值,這往往不是使用者所希望

的,即存在二義性。與其允許修改引用的值而不能實作使用者的目的,還不如不允許修改

引用的值。這就是C++規定對這類引用必須加const的原因。

繼續閱讀