在C/c++中,數組和指針有著密切的關系,有很多地方說數組就是指針式錯誤的一種說法。這兩者是不同的數據結構。其實,在C/c++中沒有所謂的二維數組,書面表達就是數組的數組。我猜想是為了表述方便才叫它二維數組。
在本文中,我也就叫它二維數組。在C/C++中,二維數組是數組的數組。數組的每一個元素是一個數組。說起來有點繞,大家都知道,一維數組也和指針那關比較密切,在本文中不重點闡述,下面就來闡述二維數組和桌指針之間到底存在著什麼樣的關系。
一、二維數組一維化
其實我這裡也只是表述的方便才叫這麼一個題目,我們怎麼利用一個數組的訪問方式來訪問二維數組呢?下面來看一個具體的例子。
首先,定義一個二維數組。
int iArr[2][3]={0,1,2,3,4,5};
我們可以用一個指向int型的指針變量來訪問這個數組,下面的代碼是將數組一維化:
int* p = iArr[0];
上面的iArr[0]就是代表第一個數組的首地址,由於二維數組在內存中的存儲也是先行後列的方式,所以第二行也緊跟第一行之後,這樣就可以用p來訪問數組的元素值了,訪問的方式有下標和指針方式。
printf("%d,",p[3]);
printf("%d\n",*(p+3));
最後輸出的結果都是4。講完了一維化之後,下面來繼續看二維數組的函數名到底是什麼意思?
二、關於二維數組名的探索
可能想當然的話,二維數組不就是一個二級指針嗎?真是這樣嗎?下面用代碼來驗證下:
int **pp = iArr;
不出意外,會出現下面的編譯錯誤:
error C2440: “初始化”: 無法從“int [2][3]”轉換為“int **”
其實二維數組名是一個數組指針,那什麼是數組指針?數組指針是指向一個數組首地址的指針,它實際上也是一種指針類型,類似於函數指針。它聲明如下:
int (*pArr)[3]
它說明pArr是一個數組指針,它指向的是一個數組元素為int類型並且數組元素的個數為3的一個數組指針,奇怪,中間的怎麼還有一個括號是啥玩意?呵呵,這個括號還真是不可少的。少了它就變為另外一種類型了:指針數組。指針數組是數組類型,代表數組的每一個元素是指針類型,它聲明如下:int *pArr[3]。
既然二維數組的數組名是指向第一行數組的首地址,我們也叫它行指針。那麼我們可以用這種數組名或者指針來訪問二維數組的元素。
int (*pArr)[3] = iArr;
下面,我要訪問第一行第二列的元素,我可以用下面的代碼來訪問
*(*(pArr+1) + 2)
也可以用數組名來訪問:
*(*(iArr+1) + 2)
這種方式是不是一下很難看懂,為什麼兩個星號啊?下面就我的理解來作一下解釋。僅以pArr做說明
首先,pArr是一個指向數組的指針,在這個指針上加減一個整數都是移動整行,而不是一個元素。比如說,pArr+1代表的現在指針已經指向第一行元素了,也就是實際中的第二行,而要取得指針所指的對象,就要用到解引用運算符*,所以*(pArr+1)就代表第一行數組,是整個這一行元素就取到了,那現在要取這一行的第二個元素,只須將指針再移動兩個元素,即*(iArr+1) + 2,這樣就指向了這個元素的地址,再解引用取得元素的值即可。說的有點啰嗦,或許有錯誤,望高手別噴就是了。
接下來請看第2頁精彩內容:http://www.linuxidc.com/Linux/2013-10/90911p2.htm