C/C++中二維數組和指標關係分析

來源:互聯網
上載者:User

        在C/c++中,數組和指標有著密切的關係,有很多地方說數組就是指標式錯誤的一種說法。這兩者是不同的資料結構。其實,在C/c++中沒有所謂的二維數組,書面表達就是數組的數組。我猜想是為了表述方便才叫它二維數組。

       在本文中,我也就叫它二維數組。在C/C++中,二維數組是數組的數組。數組的每一個元素是一個數組。說起來有點繞,大家都知道,一維數組也和指標那關比較密切,在本文中不重點闡述,下面就來闡述二維數組和指標之間到底存在著什麼樣的關係。

      一、二維數組一維化

           其實我這裡也只是表述的方便才叫這麼一個題目,我們怎麼利用一個數組的訪問方式來訪問二維數組呢?下面來看一個具體的例子。

           首先,定義一個二維數組。

         

int iArr[2][3]={0,1,2,3,4,5};


我們可以用一個指向int型的指標變數來訪問這個數組,下面的代碼是將數組一維化:

int* p = iArr[0];

上面的iArr[0]就是代表第一個數組的首地址,由於二維數組在記憶體中的儲存也是先行後列的方式,所以第二行也緊跟第一行之後,這樣就可以用p來訪問數組的元素值了,訪問的方式有下標和指標方式。

printf("%d,",p[3]);printf("%d\n",*(p+3));

最後輸出的結果都是4。講完了一維化之後,下面來繼續看二維數組的函數名到底是什麼意思?

 

        二、關於二維數組名的探索

      可能想當然的話,二維數組不就是一個二級指標嗎?真是這樣嗎?下面用代碼來驗證下:

    

int **pp = iArr;

       不出意外,會出現下面的編譯錯誤:

      error C2440: “初始化”: 無法從“int [2][3]”轉換為“int **”

      其實二維數組名是一個數組指標,那什麼是數組指標?數組指標是指向一個數組首地址的指標,它實際上也是一種指標類型,類似於函數指標。它聲明如下: 

int (*pArr)[3]

      它說明pArr是一個數組指標,它指向的是一個數組元素為int類型並且數組元素的個數為3的一個數組指標,奇怪,中間的怎麼還有一個括弧是啥玩意?呵呵,這個括弧還真是不可少的。少了它就變為另外一種類型了:指標數組。指標數組是數群組類型,代表數組的每一個元素是指標類型,它聲明如下:int  *pArr[3]。

      既然二維數組的數組名是指向第一行數組的首地址,我們也叫它行指標。那麼我們可以用這種數組名或者指標來訪問二維數組的元素。

    

int (*pArr)[3] = iArr;

下面,我要訪問第一行第二列的元素,我可以用下面的代碼來訪問

*(*(pArr+1) + 2)

也可以用數組名來訪問:

*(*(iArr+1) + 2)

這種方式是不是一下很難看懂,為什麼兩個星號啊?下面就我的理解來作一下解釋。僅以pArr做說明

首先,pArr是一個指向數組的指標,在這個指標上加減一個整數都是移動整行,而不是一個元素。比如說,pArr+1代表的現在指標已經指向第一行元素了,也就是實際中的第二行,而要取得指標所指的對象,就要用到解引用運算子*,所以*(pArr+1)就代表第一行數組,是整個這一行元素就取到了,那現在要取這一行的第二個元素,只須將指標再移動兩個元素,即*(iArr+1) + 2,這樣就指向了這個元素的地址,再解引用取得元素的值即可。說的有點囉嗦,或許有錯誤,望高手別噴就是了。

 

        三、作為函數參數

       一維數組名作為函數參數實際上是退化為指標,二維數組作為函數參數又有什麼不同呢?下面舉個例子說明。

 聲明了如下函數:

void TestFun(int *pArr,int nlength)

假設,我用數組名和指向首個元素地址的指標作為傳遞參數,看看有什麼效果?

TestFun(iArr,6);//“TestFun”: 不能將參數 1 從“int [2][3]”轉換為“int *”TestFun(&iArr[0][0],6);

直接傳遞數組名是編譯通不過的。因為數組名是數組指標,而函數的參數是int*,兩者的類型化完全不一樣,所以不能轉換。

而數組首元素的地址顯然是int*類型,所以就能編譯通過。

 

假設,我現在把這個函數的聲明換一下,看看這兩種傳參的方法會出現什麼情況?

現在的聲明是:

void TestFun(void *pArr,int nlength)

還是這樣傳參,

TestFun(iArr,6);TestFun(&iArr[0][0],6);

編譯一下,居然都能通過了。在這裡,第二種方式顯然是沒問題的,因為int*可以轉化為void*。而第一種方式怎麼就可以了呢?因為iArr是數組指標,當然也可以轉換為void*啦。

 

四、後記

     天快黑了,要吃飯去了。本文就寫到這裡,文中有什麼不對的地方,可以指出來,大家一起討論。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.