二维数组的传参数的方法
?
如何將二維數組作為函數的參數傳遞
??今天寫程序的時候要用到二維數組作參數傳給一個函數,我發現將二維數組作參數進行傳遞還不是想象得那么簡單里,但是最后我也解決了遇到的問題,所以這篇文章主要介紹如何處理二維數組當作參數傳遞的情況,希望大家不至于再在這上面浪費時間。
正文:
?
??首先,我引用了譚浩強先生編著的《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<m && 0<=j && j < n),編譯器是這樣尋址的,它的地址為:
??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] =
????{
??????{1, 1, 1},
??????{2, 2, 2},
??????{3, 3, 3}
????};
????Func(a, 3, 3);
?
??根據不同編譯器不同的設置,可能出現warning?或者error,可以進行強制轉換如下調用:?
????Func((int**)a, 3, 3);
??其實多維數組和二維數組原理是一樣的,大家可以自己擴充的多維數組,這里不再贅述。寫到這里,我先向看了這篇文章后悔的人道歉,浪費你的時間了。下面是一個完整的例子程序,這個例子程序的主要功能是求一個圖中某個頂點到其他頂點的最短路經,圖是以鄰接矩陣的形式存放的(也就是一個二維數組),其實這個函數也是挺有用的,但是我們這篇文章的重點在于將二維數組作為函數的參數傳遞。
?
//二維數組傳參問題示例 #include<iostream> using namespace std; //方法1:傳遞數組,注意第二維必須標明 void fun1(int arr[][3],int iRows) {for(int i=0;i<iRows;i++){for(int j=0;j<3;j++){cout<<arr[i][j]<<" ";}cout<<endl;}cout<<endl; } //方法二:一重指針 void fun2(int (*arr)[3],int iRows) {for(int i=0;i<iRows;i++){for(int j=0;j<3;j++){cout<<arr[i][j]<<" ";}cout<<endl;}cout<<endl; } //方法三:指針傳遞,不管是幾維數組都把他看成是指針, void fun3(int*arr,int iRows,int iCols) {for(int i=0;i<iRows;i++){for(int j=0;j<3;j++){cout<<*(arr+i*iRows+j)<<" ";}cout<<endl;}cout<<endl; } int main() {int a[2][3]={{1,2,3},{4,5,6}};fun1(a,2);cout<<endl;fun2(a,2);cout<<endl;//此處必須進行強制類型轉換,因為a是二維數組,而需要傳入的是指針//所以必須強制轉換成指針,如果a是一維數組則不必進行強制類型轉換//為什么一維數組不用強制轉換而二維數組必須轉換,此問題還沒解決,期待大牛!fun3((int*)a,2,3);cout<<endl; }
?
轉載于:https://www.cnblogs.com/aTianTianTianLan/p/4219917.html
總結
以上是生活随笔為你收集整理的二维数组的传参数的方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 笔记:编写高质量代码 改善Java程序的
- 下一篇: 鸟哥linux私房菜第6章笔记