在c語言中,根據定義,表示式 e1[e2] 準確地對應於表示式 *((e1)+(e2))。因此,要求表示式 e1[e2] 的其中乙個運算元是指標,另乙個運算元是整數。且這兩個運算元的順序可以顛倒。
故:a[4] 等同於 4[a] 等同於 *(a+4)
*
編譯器把所有的e1[e2]表示式轉換成 \((e1)+(e2))。所以,以下標的形式訪問在本質上與以指標的形式訪問沒有區別,只是寫法上不同罷了!
二維陣列a[i][j]
編譯器總是將二維陣列看成是乙個一維陣列,而一維陣列的每個元素又都是乙個陣列。
多維陣列定義的下標從前到後可以看做是最巨集觀的維到最微觀的維
。
例:三維陣列 a[i][j][k] 可理解為 共有 i 個大組,每個大組裡有 j 個小組,每個小組裡有k個元素。
所以:a 表示為整個三維陣列,其值為 &a[0][0][0]
&a+1 為整個三維陣列後面的第乙個位置。(偏移整個三維陣列的長度)
a+1 為第二個大組的首位置處(偏移乙個大組的長度)
【陣列名a代表的是陣列首元素的首位址,即:第乙個大組的首位址】
a[0] 表示為三維陣列的 i 個大組中的第乙個大組【可看做乙個二維陣列】,其值與 &a[0][0][0] 的值相同。
&a[0]+1 為第二個大組的首位置處(偏移乙個大組的長度)
a[0]+1 為第乙個大組中第二個小組的首位置處(a[0]可看做是乙個二維陣列名,故其代表的是第乙個小組的首位址)(偏移乙個小組的長度)
a[0][0] 表示為第乙個大組中的第乙個小組【可看做乙個一維陣列】,其值與 &a[0][0][0] 的值相同。
&a[0][0]+1 為第乙個大組中第二個小組的首位置處(偏移乙個小組的長度)
a[0][0]+1 為第乙個大組中第乙個小組的第二個元素位置處(偏移乙個元素的長度)
a[0][0][0] 表示為第乙個大組中的第乙個小組中的第乙個元素。其值為&a[0][0][0],a[0][0][0]+1為首元素值加1。(因為a[0][0][0]為元素值而不是位址)
陣列的陣列名(即:二維陣列名)退化為陣列的(常量)指標,而不是指標的指標。同理, n 維陣列名退化為 n-1 維陣列的(常量)指標。
【總結:指標代表的是誰的首位址 就以誰的長度為偏移單位
。】
【規律:與定義比較,缺少幾對方括號,就是幾維陣列的陣列名,如上例:a缺少3對方括號,即為3維陣列的陣列名(代表的是2維陣列的位址);a[0]缺少2對方括號,即為2維陣列的陣列名(代表的是1維陣列的位址);a[0][0]缺少1對方括號,即為1維陣列的陣列名(代表的是陣列元素的位址)】
【陣列名與整數相加,首先要轉換成陣列的首元素位址與整數相加,而首元素的儲存大小就是相加的單位】
我們可以用上面那種從前到後的解析方式來思考,
a:就表示整個多維陣列。
a[m]:就表示第m+1大組(大組即陣列最大的維),
a[m][n]:就表示第m+1大組中的第n+1小組。(小組即次大的維),
以此類推,即多維陣列的解析是層層細化的。
指標陣列:首先它是乙個陣列。陣列的元素都是指標。它是「儲存指標的陣列」的簡稱。
陣列指標:首先它是乙個指標。它指向乙個陣列。它是「指向陣列的指標」的簡稱。
例:int p1[10]; //它是指標陣列。(因為的優先順序比*高,p1先與結合,構成乙個陣列的定義)
int (*p2)[10] ; //它是陣列指標。(括號的優先順序較高,*與p2構成乙個指標的定義) 它指向乙個包含10個int型資料的陣列。
int (\p)[10][5] ; //則p指向乙個int型的二維陣列a[10][5]。
【規律:陣列指標,把定義中括號內的指標看成是乙個普通的字母,則其表示的就是 陣列指標所指的物件型別】
int a[5][5] ;設二維陣列的首位址為0,則a[4][2]為第5組的第3個位置,因為int a[5][5];即有5組,每組有5個元素。故:&a[4][2]是(4*5+2)*sizeof(int)。int (*p)[4] ;
p=a ;
問:&p[4][2]-&a[4][2]的值為多少?
int (*p)[4] ; 指標指向乙個含4個int型的元素的陣列,故p[4]相對於p[0]向後移動了「4個int型陣列」的長度,然後在此基礎上再向後移動2個int型的長度(即,其步長按維度逐步遞減,多維陣列也可按此方式理解)。最後其值為(4*4+2) sizeof(int)
最後切記:位址值參與的加減運算(位址不能被乘),整數的單位是位址值代表的元素的儲存大小!
&p[4][2]-&a[4][2]結果為-4。若分開比較&p[4][2]和&a[4][2]則相差4 sizeof(int)個位元組。
int main(void)
被調函式:
①fun( inta[4][5] )
②fun( inta[5] )
③fun( int(*a)[5] )
以上三種方式皆可。無論是那種方式,它們只是寫法不同,但編譯器的處理方式相同,都把它們看做是一維陣列指標。
因為二維陣列名退化為乙個一維陣列指標,故是以一維陣列指標的形式來傳遞二維陣列的。
int main(void)
被調函式:
①fun(int*q[4])
②fun(int *q)
③fun(int **q)
以上三種方式皆可。無論是那種方式,寫法不同,但編譯器的處理方式相同,都把它們看做是二級指標。
因為指標陣列名退化為陣列首元素的位址,即二級指標,故是以二級指標的形式來傳遞指標陣列的。
而多維陣列名退化為次維陣列的指標,即陣列指標,故是以陣列指標的形式來傳遞多維陣列的。
【c中函式實參與形參之間是傳值引用的,所以你要改變實參的值,就傳遞它的位址】
C語言 陣列與指標高階(二)
c語言中能否靈活應用指標就能看出你的c語言功底如何,接下來是我對在學習指標過程中,對一下較為苦澀概念的理解及總結。指標的運算可歸納為以下三部分 1 指標 整數 一般來說,此類運算只是左右移動指標所指向陣列元素的位置而已 若指標指向的是 陣列名,此時其加1,則移動的是乙個陣列了,不是乙個元素 2 指標...
C語言指標陣列與陣列指標
初學者總是分不出指標陣列與陣列指標的區別。其實很好理解 指標陣列 首先它是乙個陣列,陣列的元素都是指標,陣列佔多少個位元組由陣列本身決定。它是 儲存指標的陣列 的簡稱。陣列指標 首先它是乙個指標,它指向乙個陣列。在32 位系統下永遠是佔4 個位元組,至於它指向的陣列佔多少位元組,不知道。它是 指向陣...
c語言,指標與陣列 指標與二維陣列2
include typedef int tp parry1 3 define uart printf printf void f1 void a 二維陣列名 equal 指向一維陣列的指標 tp parry1 p a int q 3 a int t 2 a warning initializatio...