二維數組解析

   當我們寫下int a[3][4]; 的時候,我不知道有多少學C語言的具體明白這個數組背後隱藏的東西。

   a代表什麼,&a代表什麼,a[0]代表什麼等等。

   我們暫且放棄我們腦海中C語言老師傳授給我們的那些教條概念:“a是二維數組名,表示二維數組第一個元素的地址...”

   假設我們根本就沒有接觸過二維數組。當然我們至少得知道一維數組的知識。

   我們採用從右到左的識別變量的方式來分析二維數組:

 

   首先向右看,與a結合的是[3],即a[3],什麼意思,明白吧,a是一個包含3個元素的數組。那麼元素的類型是什麼呢,剩下的殼肯定就是它的類型薩。剩下的是:int  [4] 。哦,知道了,元素的類型是:(包含4個整形數據的一維數組)類型。

 

   a ->a[0] -->a[0][0],a[0][1],a[0][2],a[0][3]

           a[1] -->a[1][0],a[1][1],a[1][2],a[1][3]

           a[2] -->a[2][0],a[2][1],a[2][2],a[2][3]

 

  那麼a[0]具體表示什麼意思呢: a[0] = a[0]+0  = &(*(a[0]+0)) = &a[0][0], 這不就明白了嗎,a[0]表示a[0][0]的地址,

而a[0][0]是第一個一維數組的第一個元素。也就是:a[0]是第一個數組元素的第一個元素的地址。而我們根據數組名的定義,數組名錶示數組第一個元素的地址。所以a[0]即第一個數組(元素)的數組名。同理a[1]表示第二個數組的數組名,a[2]表示第三個數組的數組名。

 

   a是什麼意思? 好吧,我麼一樣來分析a = a+0 =&(*(a+0)) =&a[0] = &(a[0]+0) = &( & (*(a[0]+0)) = &&a[0][0].即a表示

第一個數組的第一個元素的地址的地址。第一個數組的第一個元素的地址即數組名a[0],所以a表示a[0]的地址,同理a+1表示a[1]的地址,a+2 表示a[2]的地址。

  a的另外一種理解: a[3] 表示a是一個包含3個元素的一維數組,a是這個一維數組的數組名,即這個一維數組的地址。a+0 =   =&(*(a+0) =&a[0] a是這個數組的第一個元素的地址(整個一維數組的地址,數組名都是一樣的),a+1=&a[0] 是這個數組第二個元素的地址。

   &a有是什麼意思?暈了吧,這裏我們就要採取更絕的方式來理解拉,一維數組的概念我們都拋一邊。a是一個變量,整個變量的類型是什麼,剩下的就是它的類型貝,哦,int [3][4] ,我們不管這後面有多麼的一大堆的東西,反正變量a現在表示的是12個整形大小(48個字節)的一片內存。這12個整形是一個整體,和我們平時的任何基本數據類型都是一樣(思想:複雜問題傻瓜化)。即假設有這麼一種基本類型,它佔用48個字節大小的一個空間。那麼,&a好理解了吧,不就是這48個這麼大小的空間的地址嗎。不過我們注意拉,&a+1表示的是下一個48字節的空間的地址。

   如果還不好理解,我們通過類型定義來看看:

   typedef   int   type48bytes[3][4];//=== typedef  int [3][4]  type48bytes;

   type48bytes  a;

 

   或者:

 

   typedef struct {

       char tmp[48];

       //int tmp[12];

       //48bytes;

   }type48bytes;

 

  type48bytes a;

 

 

  我們再來分析怎麼定義指向二維數組的指針。

  現來看看一維數組的指針是怎麼定義的:假設有  int b[4];

 

  那我們看到的肯定就是則會樣的形式: int * p  = b;

 

   爲什麼是這樣的呢(我以前沒有思考過,你們估計也沒思考過),b = b+0 = &(*(b+0)) = &b[0] 所以b就是第一個元素的地址,這個元素是int型,所以,賦值符號兩邊類型剛好對應。

 

  那二維數組呢: int a[3][4];

 

  同理: a = &a[0]  ,好了,上面分析中b[0]爲整形,所以b = &b[0] == int *, 可以推理,現在如果a[0]是什麼類型,那麼指針應該就是指向該類型的指針。a[0] 不就是 int  [4]類型嗎? 所以指針的定義應該爲: int (*p)[4];

 

  即int (*p)[4] = a;

 

  我們驗證上面的是正確的,可以知道,p指針指向的是包含4個整形那麼個大小的空間 p+1應該就是指向下一個那麼大小的空間,也就是a[1],同理p+2 指向 a[2].

 

   其實通過上面我們可以總結出這樣一條規律:即將我們等式右邊的式子表示爲:&type 則 type是什麼類型,那麼指針就是什麼類型的指針。

 

  如: int a[3]; 顯然a = &a[0]  a[0]是整形,所以指針爲int *  ;  int * p = a; 

         那麼&a呢,那不就是看a的類型嗎?a的類型不就是int [3]類型嗎?所以 int (*p)[3] =&a; 

 

 

 

         int a[3][4];  

         a[0] = &a[0][0]  所以指針類型爲a[0][0] 整形指針  int *;   int * p = a[0];

         a = &a[0]  a[0]是int [4]  類型,所以指針爲 int (*)[4];    int (*p)[4] = a;

         &a  這個有點麻煩,a是什麼類型呢,利a最近的是a[3],所以a是含有3個 int [4] 元素的數組類型,即指針類型爲,int [4]  (*)[3]

 

         = int (*)[3][4]

 

        所以 int (*p)[3][4] = &a;  

 

       哈哈,發現了規律,對於數組名取地址,總是爲  類型  (*)p[一維][二維]...[N維])  =&a;

 

       同理當地址越來越具體的話,就是依次去掉第一維,第二維,第三維,第N維;

       如:int (*p)[4]  = a

             int  *p  = a[0]; 

 

 

 

 

 

output輸出如下:

 a type=int *

 &a type=int (*)[6]

 

 p[0] type=int *

 p type=int (*)[3]

 &p type=int (*)[2][3]

 

 a=0012FF68

 &a=0012FF68

 

 p[0]=0012FF50

 p=0012FF50

 &p=0012FF50

 

 

   通過上面的分析,我們再結合老師的教條,對二維數組的理解就差不多拉。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章