二維數組和指標(C語言)

來源:互聯網
上載者:User

標籤:儲存   位元組   指標   100%   str   order   數組定義   表達   位移   

二維數組和指標

二維數組和指標1、二維數組和數組元素的地址若有以下定義:int *p, a[3][4];

 

1)二維數組a由若干個一維數組組成在C語言中定義的二維數組實際上是一個一維數組,這個一維數組的每一個成員又是一個一維數組。如以上定義的a數組,則可視a數組由a[0]、a[1]、a[2]等三個元素組成,而a[0]、a[1]、a[2]等每個元素又分別是由4個整型元素組成的一維數組。可用a[0][0]、a[0][1]等來引用a[0]中的每個元素,其它依次類推。在第二節中已解釋過,C語言中,在函數體中或在函數外部定義的一維數組名是一個地址常量,其值為數組第一個元素的地址,此地址的基底類型就是數組元素的類型。在以上二維數組中,a[0]、a[1]、a[2]都是一維數組名,同樣也代表一個不可變的地址變數,其值依次為二維數組每行第一個元素的地址,其基底類型就是數組元素的類型。因此,對於二維數組,象a[0]++這樣的運算式是非法的。若有運算式a[0]+1,運算式中1的單位應當是2個位元組。在以上定義中,指標變數p的基底類型與a[i](0≤i<3)相同,因此,指派陳述式p=a[i];是合法的。我們已知a[i]也可以寫成:*(a+i),故以上指派陳述式也可寫成:p=*(a+i);。

 

2)二維數組名也是一個地址常量二維數組名同樣也是一個存放地址常量的指標,其值為二維數組中第一個元素的地址。以上a數組,數組名a的值與a[0]的值相同,只是其基底類型為具有4個整型元素的數群組類型。即a+0的值與a[0]的值相同,a+1的值與a[1]的值相同,a+2的值與a[2]的值相同,它們分別表示a數組中第零、第一、第二行的首地址。二維數組名應理解為一個行指標。在運算式a+1中,數值1的單位應是4×2個位元組,而不是2個位元組。指派陳述式p=a;是不合法的,因為p和a的基底類型不同。同樣,對於二維數組名a,也不可以進行a++,a=a+i等運算。

 

3)二維數組元素的地址二維數組元素的地址可以由運算式&a[i][j]求得;也可以通過每行的首地址來表示。以上二維數組a中,每個元素的地址可以通過每行的首地址:a[0]、a[1]、a[2]等來表示。如:地址&a[0][0]可以用a[0]+0來表示,地址&a[0][1]可以用a[0]+1表示;若0≤i<3、0≤j<4,則a[i][j]的地址可用以下五種運算式求得:(1)&a[i][j](2)a[i]+j(3)*(a+i)+j(4)&a[0][0]+4*i+j (5)a[0]+ 4*i+j

 

在以上運算式中a[i]、&a[0][0]、a[0]的基底類型都是int類型,系統將自動據此來確定運算式中常量1的單位是2個位元組。但是不可以把求a[i][j]地址的運算式寫成:a+4*i+j,因為a的基底類型是4個整型元素的數群組類型,系統將自動據此來確定常量1的單位是8個位元組。

 

2、通過地址來引用二維數組元素若有以下定義:int a[3][4],i,j;且當0≤i<3、0≤j<4,則a數組元素可用以下五種運算式來引用:

(1)a[i][j](2)*(a[i]+j)(3)*(*(a+i)+j)(4)(*(a+i))[j](5)*(&a[0][0]+4*i+j)

 

在(2)中,運算式*(a[i]+j)中,因為a[i]的基底類型為int,j的位移量為2×j位元組。

 

在(3)中,運算式*(*(a+i)+j)中,a的基底類型為4個元素的數組,i的位移量為4×2×i位元組;而*(a+i)的基底類型為int,j的位移量仍為2×j位元組。

 

在(4)中,*(a+i)外的一對圓括弧不可少,若寫成:*(a+i)[j],因為運算子[]的優先順序高於*號,運算式可轉換成:*(*(a+i)+j)),即為:*(*(a+i+j)),這時i+j將使得位移量為4×2×(i+j)個位元組,顯示然這已不是元素a[i][j]的地址。*(*(a+i+j))等價於*(a[i+j])、等價於:a[i+j][0],引用的是數組元素a[i+j][0],而不是a[i][j],很可能早已超出數組定義的範圍。

 

在(5)中,&a[0][0]+4*i+j代表了數組元素a[i][j]的地址,通過間址運算子*號,運算式*(&a[0][0]+4*i+j)代表了數組元素a[i][j]的儲存單元。

 

3、通過建立一個指標數組來引用二維數組元素若有以下定義:int *p[3], a[3][2], i,j ;在這裡,說明符*p[3]中,也遵照運算子的優先順序,一對[]的優先順序高於*號,因此p首先與[]結合,構成p[3],說明了p是一個數組名,系統將為它開闢3個連續的儲存單元;在它前面的*號則說明了數組p是指標類型,它的每個元素都是基底類型為int的指標。若滿足條件:0≤i<3,則p[i]和a[i]的基底類型相同,p[i]= a[i]是合法的賦值運算式。

 

若有以下迴圈:for(i=0; i<3; i++) p[i]= a[i];在這裡,賦值號右邊的a[i]是常量,表示a數組每行的首地址,賦值號左邊的p[i]是指標變數,迴圈執行的結果使p[0]、p[1]、p[2]分別指向a數組每行的開頭。這時,數組p和數組a之間的關係9.6所示。

 

當p數組的每個元素指向a數組每行的開頭時,則a數組元素a[i][j]的引用形式*(a[i]+ j)和*(p[i]+j)是完全等價的。由此可見,這時可以通過指標數組p來引用a數組元素,它們的等價形式如下:(1)*(p[i]+j) (2)*(*(p+i)+j) (3)(*(p+i))[j] (4)p[i][j] 不同的是:p[i]中的值是可變的,而a[i]中的值是不可變的。

 

通過建立一個行指標來引用二維數組元素若有以下定義:int a[3][2], (*prt)[2];在這裡,說明符(*prt)[2]中,由於一對圓括弧的存在,所以*號首先與prt結合,說明prt是一個指標變數,然後再與說明符[2]結合,說明指標變數prt的基底類型是一個包含有兩個int元素的數組。在這裡,prt的基底類型與a的相同,因此prt=a;是合法的指派陳述式。prt+1等價於a+1、等價於a[1]。當prt指向a數組的開頭時,可以通過以下形式來引用a[i][j]:(1) *(prt[i]+j) (2) *(*(prt+i)+j) (3)(*(prt+i))[j] (4) prt[i][j] 在這裡,prt是個指標變數,它的值可變,而a是一個常量。

 

 

附:

#include "stdio.h"
void disp(int (*a)[3])
{
    printf("%d",*(*(a+1)+1));
}

void main()
{
    int a[2][3];
    a[0][0]=1;
    a[0][1]=2;
    a[0][2]=3;
    a[1][0]=4;
    a[1][1]=5;
    a[1][2]=6;
    disp(&a[0]);//也可以寫作disp(a);
}

二維數組和指標(C語言)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.