如何將二維陣列作為函式的引數傳遞
宣告:如果你是得道的大俠,這篇文章可能浪費你的時間,如果你堅持要看,我當然感覺很高
興,但是希望你看完了別罵我!如果你發現我這篇文章有錯誤的話,你可以提出批評以及
指正,我將很樂意地接受。*_*
概述:今天寫程式的時候要用到二維陣列作引數傳給乙個函式,我發現將二維陣列作引數進行
傳遞還不是想象得那麼簡單裡,但是最後我也解決了遇到的問題,所以這篇文章主要介紹
如何處理二維陣列當作引數傳遞的情況,希望大家不至於再在這上面浪費時間。
正文:首先,我引用了譚浩強先生編著的《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);
其實多維陣列和二維陣列原理是一樣的,大家可以自己擴充的多維陣列,這裡不再贅述
。寫到這裡,我先向看了這篇文章後悔的人道歉,浪費你的時間了。下面是乙個完整的例
子程式,這個例子程式的主要功能是求乙個圖中某個頂點到其他頂點的最短路經,圖是以
鄰接矩陣的形式存放的(也就是乙個二維陣列),其實這個函式也是挺有用的,但是我們這
篇文章的重點在於將二維陣列作為函式的引數傳遞。
完整的例子程式包括三個檔案,在microsoft visual c++ 6.0下除錯通過。如下:
//// mian.c 為主程式入口,並且呼叫了示範了如何呼叫求乙個圖中某個頂點到其他頂點
的最短路經
// 的函式
//#include "short.h"
#include
int main(),,
,,};int path[5];
float length[5];
shortestpath(adjoinmatrix, length, path, 5, 0);
for(i = 1; i < 5; i++)
printf("%d\n", v);
}return 0;}//
// shortestpath.h 中定義了求乙個圖中某個頂點到其他頂點的最短路經的函式,還定
義了乙個
// 巨集,#define no_path 0x00ffffff,如果圖中的兩個頂點之間的直接路徑的長度為
no_path,
// 表示圖中兩個頂點是不直接相通的。
//#ifndef include_shortestpath_h
#define include_shortestpath_h
#define in
#define out
#define no_path 0x00ffffff
/*++
abstract:
該函式的功能是求得乙個圖中的某個頂點到其他所有頂點的最短路經,及其最
短路經的長度
returen value:
型別是int,含義如下
0 成功
1 資源不夠
examples:
//你有乙個圖的鄰接矩陣如adjoinmatrix[n][n]和陣列
path[n], length[n](n為圖頂點的個數,
//然後你可以如下呼叫:shortestpath(adjoinmatrix,
length, path, 5, 0);
//呼叫後,path[n]中存放最短路徑,length[n]中存放著最
短路徑的長度
//下面的例子中我們求得從0頂點到其他定點的最短路經及
其長度float adjoinmatrix[5][5]=,,
,,};int path[5];
float length[5];
shortestpath(adjoinmatrix, length, path, 5,
0);int i = 0, int v =0;
for(i = 1; i < 5; i++)
printf("%d\n", v);
}--*/
int shortestpath(
in float **adjoinmatrix, //存放圖的鄰接矩陣,是
乙個二維陣列
out float *length, //用於返回到各
個點的最短路經的長度
out int *path, //用於返回最短
路經,path[i]表示在最短路經上頂點i前面的頂點
in int vertexnum, //頂點的個數
in int vertex //起始頂點
);#endif
//// shortestpath.c 中實現了求乙個圖中某個頂點到其他頂點的最短路經的函式。
//#include "shortestpath.h"
#include
/*++
abstract:
該函式的功能是求得乙個圖中的某個頂點到其他所有頂點的最短路經,及其最短
路經的長度
returen value:
型別是int,含義如下
0 成功
1 資源不夠
--*/
int shortestpath(
in float **adjoinmatrix, //存放圖的鄰接矩陣,是
乙個二維陣列
out float *length, //用於返回到各
個點的最短路經的長度
out int *path, //用於返回最短
路經,path[i]表示在最短路經上頂點i前面的頂點
in int vertexnum, //頂點的個數
in int vertex //起始頂點)//
// 初始化
//for(i = 0; i < vertexnum; i++)
else }
vertexset[vertex] = 1;
length[vertex] = 0;
//// 求得最短路經
//for(i = 0; i < vertexnum-1; i++)
}vertexset[u] = 1;
for(w = 0; w < vertexnum; w++)}}
return 0;
}
如何將二維陣列作為函式引數
1 函式宣告 將二維陣列作為函式引數的函式宣告有兩種 二維陣列型 如 int sum int ar2 size 注意 行數可不宣告,但要求列數必須要宣告,不然將發生錯誤!指標型 如int sum int ar2 list size int row size 其中row size為行數!2 函式呼叫 ...
如何將二維陣列作為函式的引數傳遞
今天寫程式的時候要用到二維陣列作引數傳給乙個函式,我發現將二維陣列作引數進行傳遞還不是想象得那麼簡單裡,但是最後我也解決了遇到的問題,所以這篇文章主要介紹如何處理二維陣列當作引數傳遞的情況,希望大家不至於再在這上面浪費時間。正文 首先,我引用了譚浩強先生編著的 c程式設計 上面的一節原文,它簡要介紹...
如何將二維陣列作為函式的引數傳遞
如何將二維陣列作為函式的引數傳遞 今天寫程式的時候要用到二維陣列作引數傳給乙個函式,我發現將二維陣列作引數進行傳遞還不是想象得那麼簡單裡,但是最後我也解決了遇到的問題,所以這篇文章主要介紹如何處理二維陣列當作引數傳遞的情況,希望大家不至於再在這上面浪費時間。正文 首先,我引用了譚浩強先生編著的 c程...