購卡網(wǎng)頁怎么制作關(guān)鍵詞優(yōu)化軟件
文章目錄
- 1. 指向多維數(shù)組的數(shù)組名
- 2. 指向多維數(shù)組的指針
- 3. 作為函數(shù)參數(shù)的多維數(shù)組
1. 指向多維數(shù)組的數(shù)組名
我們知道一維數(shù)組名的值是一個指針常量,它的類型是“指向元素類型的指針”,它指向數(shù)組的第1個元素。那么多維數(shù)組的數(shù)組名代表什么呢?
其實(shí)也差不多簡單。唯一的區(qū)別是多維數(shù)組第1維的元素實(shí)際上是另一個數(shù)組。例如,下面這個聲明:
int matrix[3][10];
matrix
數(shù)組可以看作是一個一維數(shù)組,包含3個元素,只是每個元素恰好是包含10個整型元素的數(shù)組。matrix
這個名字的值是一個指向它第1個元素的指針,所以matrix是一個指向一個包含10個整型元素的數(shù)組的指針。
那么下面各個表達(dá)式是什么意思呢?如果你能正確說出來,說明你對多維數(shù)組的數(shù)組名已經(jīng)了如指掌了~
matrix + 1
這也是一個“指向包含10個整型元素的數(shù)組的指針”,但它指向matrix
的另一行:
為什么?因?yàn)?這個值根據(jù)包含10個整型元素的數(shù)組的長度進(jìn)行調(diào)整,所以它指向matrix的下一行。
*(matrix + 1)
如果對其執(zhí)行間接訪問操作,就如下圖隨箭頭選擇中間這個子數(shù)組:
事實(shí)上它標(biāo)識了一個包含10個整型元素的子數(shù)組。數(shù)組名的值是個常量指針,它指向數(shù)組的第1個元素,在這個表達(dá)式中也是如此。它的類型是“指向整型的指針”。我們現(xiàn)在可以在下一維的上下文環(huán)境中顯示它的值:
注意間接訪問后還是一個指針,間接訪問前是一個指向一維整型數(shù)組的指針,間接訪問后是一個指向整型的指針。
*( matrix + 1 ) + 5
前一個表達(dá)式是個指向整型值的指針,所以5這個值根據(jù)整型的長度進(jìn)行調(diào)整。整個表達(dá)式的結(jié)果是一個指針,它指向的位置比原先那個表達(dá)式所指向的位置向后移動了5個整型元素。
*( *( matrix + 1 ) + 5 )
對其執(zhí)行間接訪問操作,它所訪問的正是圖中的那個整型元素。如果它作為右值使用,你就取
得存儲于那個位置的值。如果它作為左值使用,這個位置將存儲一個新值。
*( matrix[1] + 5 )
這個看上去嚇人的表達(dá)式實(shí)際上正是我們的老朋友——下標(biāo)。我們可以把子表達(dá)式matrix[1]
改寫為*(matrix + 1)
。
這個表達(dá)式是完全合法的。matrix[1]
選定一個子數(shù)組,所以它的類型是一個指向整型的指針。我們對這個指針加上5,然后執(zhí)行間接訪問操作。
matrix[1][5]
這個就是我們最常見的表達(dá)形式了。用下標(biāo)代替間接訪問,其含義和4、5一樣。
2. 指向多維數(shù)組的指針
下面這些聲明合法嗎?
int vector[10], *vp = vector;
int matrix[3][10], *mp = matrix;
1個聲明是合法的。它為一個整型數(shù)組分配內(nèi)存,并把vp聲明為一個指向整型的指針,并把它初始化為指向vector數(shù)組的第1個元素。vector和vp具有相同的類型:指向整型的指針。但是,第2個聲明是非法的。它正確地創(chuàng)建了matrix數(shù)組,并把mp聲明為一個指向整型的指針。但是,
mp的初始化是不正確的,因?yàn)?strong>matrix并不是一個指向整型的指針,而是一個指向整型數(shù)組的指針。我們應(yīng)該怎樣聲明一個指向整型數(shù)組的指針的呢?
int (*p)[10];
下標(biāo)引用的優(yōu)先級高于間接訪問,但由于括號的存在,首先執(zhí)行的還是間接訪問。所以,p是個指針,但它指向什么呢?接下來執(zhí)行的是下標(biāo)引用,所以p指向某種類型的數(shù)組。這個聲明表達(dá)式中并沒有更多的操作符,所以數(shù)組的每個元素都是整數(shù)。
我們對它執(zhí)行間接訪問操作時,我們得到的是個數(shù)組,對該數(shù)組進(jìn)行下標(biāo)引用操作得到的是一個整型值。所以p是一個指向整型數(shù)組的指針。
int (*p)[10] = matrix;
它使p指向matrix的第1行。p是一個指向擁有10個整型元素的數(shù)組的指針。當(dāng)你把p與一個整數(shù)
相加時,該整數(shù)值首先根據(jù)10個整型值的長度進(jìn)行調(diào)整,然后再執(zhí)行加法。所以我們可以使用這個指針一行一行地在matrix中移動。
不要想當(dāng)然地認(rèn)為一維數(shù)組的數(shù)組名是
int *
,二維數(shù)組是int **
,兩者還是有明顯差別的。
如果需要一個指針逐個訪問整型元素而不是逐行在數(shù)組中移動,應(yīng)該怎么辦呢?下面兩個聲明都創(chuàng)建了一個簡單的整型指針,并以兩種不同的方式進(jìn)行初始化,指向matrix的第1個整型元素。
int *pi = &matrix[0][0];
int *pi = matrix[0];
增加這個指針的值使它指向下一個整型元素。
如果你打算在指針上執(zhí)行任何指針運(yùn)算,應(yīng)該避免這種類型的聲明:
int (*p)[] = matrix;
p仍然是一個指向整型數(shù)組的指針,但數(shù)組的長度卻不見了。當(dāng)某個整數(shù)與這種類型的指針執(zhí)行指針運(yùn)算時,它的值將根據(jù)空數(shù)組的長度進(jìn)行調(diào)整(也就是說,與零相乘),這很可能不是你所設(shè)想的。有些編譯器可以捕捉到這類錯誤,但有些編譯器卻不能。所以不要在一個指向未指定長度的數(shù)組的指針上執(zhí)行指針運(yùn)算。
3. 作為函數(shù)參數(shù)的多維數(shù)組
作為函數(shù)參數(shù)的多維數(shù)組名的傳遞方式和一維數(shù)組名相同——實(shí)際傳遞的是個指向數(shù)組第1個元素的指針。但是,兩者之間的區(qū)別在于,多維數(shù)組的每個元素本身是另外一個數(shù)組,編譯器需要知道它的維數(shù),以便為函數(shù)形參的下標(biāo)表達(dá)式進(jìn)行求值。
- 一維數(shù)組:
int vector[10];
...
func1(vector);
參數(shù)vector的類型是指向整型的指針,所以func1的原型可以是下面兩種中的任何一種:
void func1( int *vec );
void func1(int vec[] );
作用于vec上面的指針運(yùn)算把整型的長度作為它的調(diào)整因子。
- 多維數(shù)組:
int matrix[3][10];
...
func2( matrix );
參數(shù)matrix的類型是指向包含10個整型元素的數(shù)組的指針。func2的原型應(yīng)該是怎樣的呢?
void func2( int (*mat)[10] );
void func2( int mat[][10] );
在這個函數(shù)中,mat的第1個下標(biāo)根據(jù)包含10個元素的整型數(shù)組的長度進(jìn)行調(diào)整,接著第2個下標(biāo)根據(jù)整型的長度進(jìn)行調(diào)整,這和原先的matrix數(shù)組一樣。
這里的關(guān)鍵在于編譯器必須知道第2個及以后各維的長度才能對各下標(biāo)進(jìn)行求值,因此在原型中必須聲明這些維的長度。第1維的長度并不需要,因?yàn)樵谟嬎阆聵?biāo)值時用不到它。
在編寫一維數(shù)組形參的函數(shù)原型時,你既可以把它寫成數(shù)組的形式,也可以把它寫成指針的形式。但是,對于多維數(shù)組,只有第1維可以進(jìn)行如此選擇。尤其是,把func2寫成下面這樣的原型是不正確的:
void func2( int **mat );
這個例子把mat聲明為一個指向整型指針的指針,它和指向整型數(shù)組的指針并不是一回事。
參考
- 《C和指針》