二維陣列名充當函式引數

2021-06-07 15:59:37 字數 1794 閱讀 7273

正文:

首先,我引用了譚浩強先生編著的《c程式設計》上面的一節原文,它簡要介紹了如何

將二維陣列作為引數傳遞,原文如下(略有改變,請原諒):

[原文開始]

可以用二維陣列名作為實參或者形參,在被呼叫函式中對形引數組定義時可以可以指

定所有維數的大小,也可以省略第一維的大**明,如:

void   func(int   array[3][10]);

void   func(int   array[10]);

二者都是合法而且等價,但是不能把第二維或者更高維的大小省略,如下面的定義是

不合法的:

void   func(int   array);

因為從實參傳遞來的是陣列的起始位址,在記憶體中按陣列排列規則存放(按行存放),

而並不區分行和列,如果在形參中不說明列數,則系統無法決定應為多少行多少列,不能

只指定一維而不指定第二維,下面寫法是錯誤的:

void   func(int   array[3]);實參陣列維數可以大於形引數組,例如實參陣列定義為

: void   func(int   array[3][10]);

而形引數組定義為:

int   array[5][10];

這時形引數組只取實參陣列的一部分,其餘部分不起作用。

[原文結束]

大家可以看到,將二維陣列當作引數的時候,必須指明所有維數大小或者省略第一維的

,但是不能省略第二維或者更高維的大小,這是由編譯器原理限制的。大家在學編譯原理

這麼課程的時候知道編譯器是這樣處理陣列的:

對於陣列   int   p[m][n];

如果要取p[i][j]的值(i> =0   &&   i p   +   i*n   +   j;

從以上可以看出,如果我們省略了第二維或者更高維的大小,編譯器將不知道如何正確

的定址。但是我們在編寫程式的時候卻需要用到各個維數都不固定的二維陣列作為引數,

這就難辦了,編譯器不能識別阿,怎麼辦呢?不要著急,編譯器雖然不能識別,但是我們

完全可以不把它當作乙個二維陣列,而是把它當作乙個普通的指標,再另外加上兩個引數

指明各個維數,然後我們為二維陣列手工定址,這樣就達到了將二維陣列作為函式的引數

傳遞的目的,根據這個思想,我們可以把維數固定的引數變為維數隨即的引數,例如:

void   func(int   array[3][10]);  

void   func(int   array[10]);

變為:

void   func(int   **array,   int   m,   int   n);

在轉變後的函式中,array[i][j]這樣的式子是不對的(不信,大家可以試一下),因為

編譯器不能正確的為它定址,所以我們需要模仿編譯器的行為把array[i][j]這樣的式子

手工轉變為

*((int*)array   +   n*i   +   j);

在呼叫這樣的函式的時候,需要注意一下,如下面的例子:

int   a[3][3]   =  

, ,

}; func(a,   3,   3);

根據不同編譯器不同的設定,可能出現warning   或者error,可以進行強制轉換如下呼叫

:    

func((int**)a,   3,   3);

其實多維陣列和二維陣列原理是一樣的,大家可以自己擴充的多維陣列,這裡不再贅述

。寫到這裡,我先向看了這篇文章後悔的人道歉,浪費你的時間了。

二維陣列和二維陣列名

對於一位陣列我們認識到其資料元素在記憶體中是按線性順序依次排列的,且一維陣列名的值是乙個指標常量。那麼二維陣列在記憶體中又是怎麼儲存的,其陣列名又有什麼含義呢?定義乙個二維陣列 int arr 3 4 我們可以將乙個二維陣列看做是乙個其中元素為陣列的乙個一位陣列,也就是說二維陣列第一維的元素實際上是...

二維陣列名 二維陣列名取位址 二級指標

先給出結論,便於以後查閱 首先給出幾個定義 typedef int p1x4 4 定義資料型別,p1x4這種型別為指向含4個int元素的1維陣列的指標 typedef int p3x4 3 4 定義資料型別,p3x4這種型別為指向含3x4個int元素的2維陣列的指標 下面從一維陣列說起 定義 int...

二維陣列名做引數傳遞問題

在用二維陣列名作為引數傳遞時容易出現segmention error。這是因為不能正確為二維陣列中元素定址的問題,正確的方法如下 1.用指向一維陣列的指標變數,如下例子所示 cpp view plain copy print?include include define n 4 void testa...