《指標和引用小結》

kehr發表於2012-10-26

指標和引用小結

 

對於指標,學C的時候以為自己理解了。最近看C++書才發現還有好多東西要學。由於C++引入了“引用”概念,這次就把自己的理解和書上的東西做一個小結。

對於指標,這是C語言中的一個重要的概念。

一、         什麼是指標?

指標是一種特殊的變數,它具有名字、型別、值。它和一般變數的區別在於值和型別上。

二、         變數在記憶體中的表示。

變數被定義後,在記憶體中佔用一塊空間。這個空間有兩個值:變數的值和變數的地址。

指標變數儲存的是地址。這是指標存在的意義。就好像人活著總要意味著什麼。指標的存在有它存在的必要性。

三、指標簡單運用

     指標的運用主要涉及到兩個一元運算子:*和&。“*”的作用是取指標所指向變數的具體值,“&”用於取變數的地址(注意:區別於引用的“&”)。

     指標一旦定義,如果值不再改變。例如:intb; int* a = b; 那麼,對於b的操作完全可以用*a來代替。因為*a和b是等價的,它們都代表著同一塊記憶體的值。

      (注:指標的定義推薦用:型別* 變數(例如:int* a;)格式,而不用:int*a。因為推薦格式更能體現指標的型別)

 

四、區別:指標陣列 和指向一維陣列的指標

     先看一下二者的定義格式:

指標陣列:         int* a[10]; //陣列a有十個元素,每個元素都是指向整形變數的指標

指向一維陣列的指標:int (*p)[5];//p是一個二級指標,指向一個具有五個元素的一維陣列

     這裡重點討論“指向一維陣列的指標”。

     指向一位陣列的指標是一個二級指標,常用它來指向二維陣列中的某一行。(二維陣列的行數就是一個一維數組)

      它的定義和運用:

             Int a[10][5], (*p)[5];

             P = a;//p指向二維陣列的第0行

             P = a+1;// p指向二維陣列的第1行

             ……

             以此類推。

c/c++不支援將二維陣列名直接賦值給一個通過int** p;形式定義的二級指標。如果想用指標運算元組只能定義一個指向陣列的指標。

與此類似,還有指向函式的指標和指標函式。

五、陣列名

其實,陣列名本身就是一個地址。書上說“陣列名是一個常量指標”,但是我個人更傾向於“陣列名是地指”的說法。經測試,對於陣列a[10][10],  a和&a 按%x輸出,其值是一樣的。同理,a+1和a[1]和*(a+1)的值是一樣的,它們都表示陣列第1行元素的首地址。

同時,將陣列名作為地址來理解,我覺得更方便分析問題。

六、引用

首先,要清除的理解什麼是引用。

簡單的說,引用就是某個變數或者物件的別名。引用不是變數或者物件,引用不佔用記憶體空間。要牢記“引用就是某個變數或者物件的別名”這一概念。因此。引用的地址就是被引用的變數或物件的地址,引用的值,就是被引用的變數或物件的值,引用的型別,就是被引用的變數或物件型別。再次廢話,引用就是給變數或物件改了個名字。(這一點類似於typedef。不過ty[edef是給型別改名字,引用是給變數或類改名字。嗯……,我是這麼認為的)

引用的操作完全類似於指標的操作(廢話!要不怎麼都放在一章講呢?,自嘲……),但是有幾點需要注意:

1、指標式變數,但是引用不是變數。(引用就是某個變數或者物件的別名,牢記啊!)

2、指標可以引用,但引用不可引用。

Eg:int* p; int*& pp = p; 這樣定義後就相當於給指標p又起了一個名字,那麼今後p就等價於pp了,除了名字不同,其它都一樣。如果:int a = 10; pp = &m; 那麼pp == p == 10。

3、指標可以作為陣列元素,但引用不可以。

例如:int* a[10];是合法的,但int& b[10];不成立。

4、指標可以賦值為空,但是引用不可以。所以,一般都要求引用必須被初始化。

 

說了這麼多引用的壞話,該說點好的了。其實,C++之所以引入引用,是有它的道理的(好吧,我承認有又是廢話)。引用作為函式引數時,用起來要比指標更加簡潔方便。畢竟只是改了個名字而已,又不需要像指標一樣開闢空間,但是同樣能夠達到指標的效果。大家都知道,用指標操作時,有時會存在很大的風險,而引用就相對安全一些。(又是一年三月三,指標飛滿天,好可怕呀!好可怕!)

 

暫時就這麼多了,貼上來就是希望能與大家交流,若有不足之處,望請大家批評指正!

相關文章