1. 程式人生 > >一維指標和二維指標指向二維陣列的一些問題

一維指標和二維指標指向二維陣列的一些問題

廢話少說,先上自己Dev c++上的程式碼: #include<stdio.h>int main (){int c[2][3]={15,2,3,4,5,6},*p,(*rp)[3],*q,i; p =(int*)c; rp=c; q=c; printf ("**rp=%d\n *rp=%p\n c=%p\n p = %p\n q=%p\n *q=%d\n ",**rp,*rp,c,p,q,*q); printf("*(rp+1)=%p\n*(p + 1)=%p\n", rp+1,p +1);for(i=0;i<6;i++){ printf("*rp[%d]=%d\n",i,*rp
[i]);
} printf("\n");for(i=0;i<6;i++){ printf("q[%d]=%d\n",i,q[i]);}return0;} 首先定義一個2*3的二維陣列,定義一個一維指標p和q,定義一個指向指標的指標(*rp)[3],問題來了! 一.將二維陣列地址賦給一維指標的問題: 第一種賦值方法:將二維陣列c強制轉換成一維的指標型別,並將其賦給一維指標p(程式碼第4行) 第二種賦值方法:將二維陣列c的地址直接賦給一維指標(程式碼第6行) 第一種賦值方法和第二種賦值方法的區別是:第一種賦值方法可以通過Dev c++的編譯,第二種賦值方法不能通過Dev C++的cpp檔案編譯(會出現error),在後綴名為c 的檔案中會出現warning(警告的中文意思是指標型別不匹配),但可以執行!
兩者執行得結果均為
因此兩種的賦值方法在本質上區別不大,但通過查閱資料得知,c++對指標的要求很嚴格,因此建議如果要用一維指標指向二維陣列時候,採用第一種直接強制型別轉換的方法比較合法規範,這樣會避免出現無可預知的錯誤! 二.一維指標和二維指標的偏移地址問題 在程式碼的定義型別上,(*rp)[3]表示指向含3個元素的一維整形陣列的指標變數,通俗的說法是指向指標的指標,也即是二維指標,為了規範,我用強制型別轉換的一維指標p與二維指標rp就偏移地址的問題做一個比較。 程式碼第八行:printf("*(rp+1)=%p\n*(p + 1)=%p\n", rp+1,p + 1); 執行的結果是:

再與初始定義的地址相比較:
仔細比較後發現,一維指標和二維指標偏移地址為1時候,一維指標地址偏移了4,二維指標地址偏移了12(指標地址都是以16進製表示) 原因:二維指標rp的首地址是c[0],一維指標p的首地址是c[0][0],因此rp+1的地址即是c[0]+1==c[1]的地址(這個地址同時也是c[1][0]的地址,p+1的地址即是c[0][0]+1==c[0][1]的地址 (如果不懂,可以參考一下中山大學2011年軟體學院的程式設計理論考試關於指標的一道填空題來理解: 填空題有一問是:*q+3-p=? 參考答案是6,下面就用上面的分析來解釋答案為什麼是6 #include<stdio.h>int main(){int a[3][4]={1,5,8,10,11,3,4,8,7};int*p =(int*)a;int(*q)[4]= a; p +=1; q +=1; printf("%d\n",*p); printf("%d\n",**q); printf("%d\n",(*q)[2]); printf("%d\n",*q+3-p); printf("*q=%p\n",*q); printf("p=%p\n", p);return0;} p是一維指標,初始地址為a[0][0],所以p+1的地址為a[0][1],q是二維指標,初始地址為a[0],所以q+1的地址為a[1][0], 程式執行後的結果如下
所以p和q的地址相差3(0x10-0x04=12,12/4=3),再加3即為答案6! 這就是一維陣列和二維陣列的地址偏移的大致區別。