如何将二维数组作为函数的参数传递
生活随笔
收集整理的這篇文章主要介紹了
如何将二维数组作为函数的参数传递
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
如何將二維數(shù)組作為函數(shù)的參數(shù)傳遞
聲明:
??如果你是得道的大俠,這篇文章可能浪費你的時間,如果你堅持要看,我當然感覺很高
興,但是希望你看完了別罵我!如果你發(fā)現(xiàn)我這篇文章有錯誤的話,你可以提出批評以及
指正,我將很樂意地接受。*_*
概述:
??今天寫程序的時候要用到二維數(shù)組作參數(shù)傳給一個函數(shù),我發(fā)現(xiàn)將二維數(shù)組作參數(shù)進行
傳遞還不是想象得那么簡單里,但是最后我也解決了遇到的問題,所以這篇文章主要介紹
如何處理二維數(shù)組當作參數(shù)傳遞的情況,希望大家不至于再在這上面浪費時間。
正文:
??首先,我引用了譚浩強先生編著的《C程序設計》上面的一節(jié)原文,它簡要介紹了如何
將二維數(shù)組作為參數(shù)傳遞,原文如下(略有改變,請原諒):
??[原文開始]
????可以用二維數(shù)組名作為實參或者形參,在被調(diào)用函數(shù)中對形參數(shù)組定義時可以可以指
定所有維數(shù)的大小,也可以省略第一維的大小說明,如:
????void?Func(int?array[3][10]);
????void?Func(int?array[][10]);
????二者都是合法而且等價,但是不能把第二維或者更高維的大小省略,如下面的定義是
不合法的:
????void?Func(int?array[][]);
????因為從實參傳遞來的是數(shù)組的起始地址,在內(nèi)存中按數(shù)組排列規(guī)則存放(按行存放),
而并不區(qū)分行和列,如果在形參中不說明列數(shù),則系統(tǒng)無法決定應為多少行多少列,不能
只指定一維而不指定第二維,下面寫法是錯誤的:
????void?Func(int?array[3][]);實參數(shù)組維數(shù)可以大于形參數(shù)組,例如實參數(shù)組定義為
:
????void?Func(int?array[3][10]);
????而形參數(shù)組定義為:
????int?array[5][10];
????這時形參數(shù)組只取實參數(shù)組的一部分,其余部分不起作用。
??[原文結束]
??大家可以看到,將二維數(shù)組當作參數(shù)的時候,必須指明所有維數(shù)大小或者省略第一維的
,但是不能省略第二維或者更高維的大小,這是由編譯器原理限制的。大家在學編譯原理
這么課程的時候知道編譯器是這樣處理數(shù)組的:
??對于數(shù)組?int?p[m][n];
??如果要取p[i][j]的值(i>=0?&&?i<m?&&?0<=j?&&?j?<?n),編譯器是這樣尋址的,它的
地址為:
??p?+?i*n?+?j;
??從以上可以看出,如果我們省略了第二維或者更高維的大小,編譯器將不知道如何正確
的尋址。但是我們在編寫程序的時候卻需要用到各個維數(shù)都不固定的二維數(shù)組作為參數(shù),
這就難辦了,編譯器不能識別阿,怎么辦呢?不要著急,編譯器雖然不能識別,但是我們
完全可以不把它當作一個二維數(shù)組,而是把它當作一個普通的指針,再另外加上兩個參數(shù)
指明各個維數(shù),然后我們?yōu)槎S數(shù)組手工尋址,這樣就達到了將二維數(shù)組作為函數(shù)的參數(shù)
傳遞的目的,根據(jù)這個思想,我們可以把維數(shù)固定的參數(shù)變?yōu)榫S數(shù)隨即的參數(shù),例如:
????void?Func(int?array[3][10]);?
????void?Func(int?array[][10]);
??變?yōu)?#xff1a;
????void?Func(int?**array,?int?m,?int?n);
??在轉變后的函數(shù)中,array[i][j]這樣的式子是不對的(不信,大家可以試一下),因為
編譯器不能正確的為它尋址,所以我們需要模仿編譯器的行為把array[i][j]這樣的式子
手工轉變?yōu)?
????*((int*)array?+?n*i?+?j);
????在調(diào)用這樣的函數(shù)的時候,需要注意一下,如下面的例子:
????int?a[3][3]?=?
????{
??????{1,?1,?1},
??????{2,?2,?2},
??????{3,?3,?3}
????};
????Func(a,?3,?3);
??根據(jù)不同編譯器不同的設置,可能出現(xiàn)warning?或者error,可以進行強制轉換如下調(diào)用
:??
????Func((int**)a,?3,?3);
??其實多維數(shù)組和二維數(shù)組原理是一樣的,大家可以自己擴充的多維數(shù)組,這里不再贅述
。寫到這里,我先向看了這篇文章后悔的人道歉,浪費你的時間了。下面是一個完整的例
子程序,這個例子程序的主要功能是求一個圖中某個頂點到其他頂點的最短路經(jīng),圖是以
鄰接矩陣的形式存放的(也就是一個二維數(shù)組),其實這個函數(shù)也是挺有用的,但是我們這
篇文章的重點在于將二維數(shù)組作為函數(shù)的參數(shù)傳遞。
??完整的例子程序包括三個文件,在Microsoft?Visual?C++?6.0下調(diào)試通過。如下:
??//
??//?mian.c?為主程序入口,并且調(diào)用了示范了如何調(diào)用求一個圖中某個頂點到其他頂點
的最短路經(jīng)
??//?的函數(shù)
??//
#include?"short.h"
#include?<stdio.h>
int?main()
{
int?i?=?0,?v?=?0;
float?AdjoinMatrix[5][5]=
{
{0, 10,NO_PATH,30,100},
{NO_PATH,0,50,NO_PATH,NO_PATH},
{NO_PATH,NO_PATH,0,NO_PATH,10},
{NO_PATH,NO_PATH,20,0,60},
{NO_PATH,NO_PATH,NO_PATH,NO_PATH,0}
};
int?Path[5];
float?Length[5];
ShortestPath(AdjoinMatrix,?Length,?Path,?5,?0);
for(i?=?1;?i?<?5;?i++)
{
v?=?i;
while(v?!=?0)
{
printf("%d?",?v);
v?=?Path[v];
}
printf("%d\n",?v);
}
return?0;
}
??//
??//?ShortestPath.h?中定義了求一個圖中某個頂點到其他頂點的最短路經(jīng)的函數(shù),還定
義了一個
??//?宏,#define??NO_PATH?0x00ffffff,如果圖中的兩個頂點之間的直接路徑的長度為
NO_PATH,
??//?表示圖中兩個頂點是不直接相通的。
??//
#ifndef?INCLUDE_SHORTESTPATH_H
#define?INCLUDE_SHORTESTPATH_H
#define?IN
#define?OUT
#define??NO_PATH?0x00ffffff
/*++
Abstract:
??該函數(shù)的功能是求得一個圖中的某個頂點到其他所有頂點的最短路經(jīng),及其最
短路經(jīng)的長度
??
Returen?value:
??類型是int,含義如下
??0 成功
??1???資源不夠
??
Examples:
??//你有一個圖的鄰接矩陣如AdjoinMatrix[n][n]和數(shù)組
Path[n],?Length[n](n為圖頂點的個數(shù),
??//然后你可以如下調(diào)用:ShortestPath(AdjoinMatrix,?
Length,?Path,?5,?0);
??//調(diào)用后,Path[n]中存放最短路徑,Length[n]中存放著最
短路徑的長度
??//下面的例子中我們求得從0頂點到其他定點的最短路經(jīng)及
其長度
??
float?AdjoinMatrix[5][5]=
{
{0, 10,NO_PATH,30,100},
{NO_PATH,0,50,NO_PATH,NO_PATH},
{NO_PATH,NO_PATH,0,NO_PATH,10},
{NO_PATH,NO_PATH,20,0,60},
{NO_PATH,NO_PATH,NO_PATH,NO_PATH,0}
};
int?Path[5];
float?Length[5];
??ShortestPath(AdjoinMatrix,?Length,?Path,?5,?
0);
??
int?i?=?0,?int?v?=0;
for(i?=?1;?i?<?5;?i++)
{
v?=?i;
while(v?!=?0)
{
printf("%d?",?v);
v?=?Path[v];
}
printf("%d\n",?v);
}
--*/
int?ShortestPath(
IN??float?**AdjoinMatrix, //存放圖的鄰接矩陣,是
一個二維數(shù)組
OUT?float?*Length, //用于返回到各
個點的最短路經(jīng)的長度
OUT?int???*Path, //用于返回最短
路經(jīng),Path[i]表示在最短路經(jīng)上頂點i前面的頂點
IN??int???VertexNum, //頂點的個數(shù)
IN??int???Vertex //起始頂點
);
#endif
??//
??//?ShortestPath.c?中實現(xiàn)了求一個圖中某個頂點到其他頂點的最短路經(jīng)的函數(shù)。
??//
#include?"ShortestPath.h"
#include?<stdlib.h>
/*++
Abstract:
該函數(shù)的功能是求得一個圖中的某個頂點到其他所有頂點的最短路經(jīng),及其最短
路經(jīng)的長度
Returen?value:
類型是int,含義如下
0 成功
1???資源不夠
--*/
int?ShortestPath(
IN??float?**AdjoinMatrix, //存放圖的鄰接矩陣,是
一個二維數(shù)組
OUT?float?*Length, //用于返回到各
個點的最短路經(jīng)的長度
OUT?int???*Path, //用于返回最短
路經(jīng),Path[i]表示在最短路經(jīng)上頂點i前面的頂點
IN??int???VertexNum, //頂點的個數(shù)
IN??int???Vertex //起始頂點
)
{
int?i?=?0,?j?=?0,?w?=?0;
//
//?已經(jīng)在最短路經(jīng)中的點的集合,如果VertexSet[i]不為0,則表示第
i個點在該集合中
//
int?*VertexSet?=?(int*)malloc(VertexNum);
if(VertexSet?==?NULL)
{
return?1; //缺乏內(nèi)存資源
}
//
//?初始化
//
for(i?=?0;?i?<?VertexNum;?i++)
{
Length[i]?=?*((float*)AdjoinMatrix?+?Vertex*VertexNum?
+?i);
VertexSet[i]=0;
if(i?!=?Vertex?&&?Length[i]?<?NO_PATH)
{
Path[i]=Vertex;
}
else
{
Path[i]?=?-1;
}
}
VertexSet[Vertex]?=?1;
Length[Vertex]?=?0;
//
//?求得最短路經(jīng)
//
for(i?=?0;?i?<?VertexNum-1;?i++)
{
float?min?=?NO_PATH;
int?u?=?Vertex;
for(j?=?0;?j?<?VertexNum;?j++)
{
if(?!VertexSet[j]?&&?Length[j]?<?min)
{
u?=?j;
min?=?Length[j];
}
}
VertexSet[u]?=?1;
for(w?=?0;?w?<?VertexNum;?w++)
{
if(!VertexSet[w]?&&?*((float*)AdjoinMatrix?+?
u*VertexNum?+?w)?<?NO_PATH?&&?Length[u]+*((float*)AdjoinMatrix?+?u*VertexNum?+?
w)?<?Length[w])
{
Length[w]?=?Length[u]?+?
*((float*)AdjoinMatrix?+?u*VertexNum?+?w);
Path[w]?=?u;
}
}
}
return?0;
}
聲明:
??如果你是得道的大俠,這篇文章可能浪費你的時間,如果你堅持要看,我當然感覺很高
興,但是希望你看完了別罵我!如果你發(fā)現(xiàn)我這篇文章有錯誤的話,你可以提出批評以及
指正,我將很樂意地接受。*_*
概述:
??今天寫程序的時候要用到二維數(shù)組作參數(shù)傳給一個函數(shù),我發(fā)現(xiàn)將二維數(shù)組作參數(shù)進行
傳遞還不是想象得那么簡單里,但是最后我也解決了遇到的問題,所以這篇文章主要介紹
如何處理二維數(shù)組當作參數(shù)傳遞的情況,希望大家不至于再在這上面浪費時間。
正文:
??首先,我引用了譚浩強先生編著的《C程序設計》上面的一節(jié)原文,它簡要介紹了如何
將二維數(shù)組作為參數(shù)傳遞,原文如下(略有改變,請原諒):
??[原文開始]
????可以用二維數(shù)組名作為實參或者形參,在被調(diào)用函數(shù)中對形參數(shù)組定義時可以可以指
定所有維數(shù)的大小,也可以省略第一維的大小說明,如:
????void?Func(int?array[3][10]);
????void?Func(int?array[][10]);
????二者都是合法而且等價,但是不能把第二維或者更高維的大小省略,如下面的定義是
不合法的:
????void?Func(int?array[][]);
????因為從實參傳遞來的是數(shù)組的起始地址,在內(nèi)存中按數(shù)組排列規(guī)則存放(按行存放),
而并不區(qū)分行和列,如果在形參中不說明列數(shù),則系統(tǒng)無法決定應為多少行多少列,不能
只指定一維而不指定第二維,下面寫法是錯誤的:
????void?Func(int?array[3][]);實參數(shù)組維數(shù)可以大于形參數(shù)組,例如實參數(shù)組定義為
:
????void?Func(int?array[3][10]);
????而形參數(shù)組定義為:
????int?array[5][10];
????這時形參數(shù)組只取實參數(shù)組的一部分,其余部分不起作用。
??[原文結束]
??大家可以看到,將二維數(shù)組當作參數(shù)的時候,必須指明所有維數(shù)大小或者省略第一維的
,但是不能省略第二維或者更高維的大小,這是由編譯器原理限制的。大家在學編譯原理
這么課程的時候知道編譯器是這樣處理數(shù)組的:
??對于數(shù)組?int?p[m][n];
??如果要取p[i][j]的值(i>=0?&&?i<m?&&?0<=j?&&?j?<?n),編譯器是這樣尋址的,它的
地址為:
??p?+?i*n?+?j;
??從以上可以看出,如果我們省略了第二維或者更高維的大小,編譯器將不知道如何正確
的尋址。但是我們在編寫程序的時候卻需要用到各個維數(shù)都不固定的二維數(shù)組作為參數(shù),
這就難辦了,編譯器不能識別阿,怎么辦呢?不要著急,編譯器雖然不能識別,但是我們
完全可以不把它當作一個二維數(shù)組,而是把它當作一個普通的指針,再另外加上兩個參數(shù)
指明各個維數(shù),然后我們?yōu)槎S數(shù)組手工尋址,這樣就達到了將二維數(shù)組作為函數(shù)的參數(shù)
傳遞的目的,根據(jù)這個思想,我們可以把維數(shù)固定的參數(shù)變?yōu)榫S數(shù)隨即的參數(shù),例如:
????void?Func(int?array[3][10]);?
????void?Func(int?array[][10]);
??變?yōu)?#xff1a;
????void?Func(int?**array,?int?m,?int?n);
??在轉變后的函數(shù)中,array[i][j]這樣的式子是不對的(不信,大家可以試一下),因為
編譯器不能正確的為它尋址,所以我們需要模仿編譯器的行為把array[i][j]這樣的式子
手工轉變?yōu)?
????*((int*)array?+?n*i?+?j);
????在調(diào)用這樣的函數(shù)的時候,需要注意一下,如下面的例子:
????int?a[3][3]?=?
????{
??????{1,?1,?1},
??????{2,?2,?2},
??????{3,?3,?3}
????};
????Func(a,?3,?3);
??根據(jù)不同編譯器不同的設置,可能出現(xiàn)warning?或者error,可以進行強制轉換如下調(diào)用
:??
????Func((int**)a,?3,?3);
??其實多維數(shù)組和二維數(shù)組原理是一樣的,大家可以自己擴充的多維數(shù)組,這里不再贅述
。寫到這里,我先向看了這篇文章后悔的人道歉,浪費你的時間了。下面是一個完整的例
子程序,這個例子程序的主要功能是求一個圖中某個頂點到其他頂點的最短路經(jīng),圖是以
鄰接矩陣的形式存放的(也就是一個二維數(shù)組),其實這個函數(shù)也是挺有用的,但是我們這
篇文章的重點在于將二維數(shù)組作為函數(shù)的參數(shù)傳遞。
??完整的例子程序包括三個文件,在Microsoft?Visual?C++?6.0下調(diào)試通過。如下:
??//
??//?mian.c?為主程序入口,并且調(diào)用了示范了如何調(diào)用求一個圖中某個頂點到其他頂點
的最短路經(jīng)
??//?的函數(shù)
??//
#include?"short.h"
#include?<stdio.h>
int?main()
{
int?i?=?0,?v?=?0;
float?AdjoinMatrix[5][5]=
{
{0, 10,NO_PATH,30,100},
{NO_PATH,0,50,NO_PATH,NO_PATH},
{NO_PATH,NO_PATH,0,NO_PATH,10},
{NO_PATH,NO_PATH,20,0,60},
{NO_PATH,NO_PATH,NO_PATH,NO_PATH,0}
};
int?Path[5];
float?Length[5];
ShortestPath(AdjoinMatrix,?Length,?Path,?5,?0);
for(i?=?1;?i?<?5;?i++)
{
v?=?i;
while(v?!=?0)
{
printf("%d?",?v);
v?=?Path[v];
}
printf("%d\n",?v);
}
return?0;
}
??//
??//?ShortestPath.h?中定義了求一個圖中某個頂點到其他頂點的最短路經(jīng)的函數(shù),還定
義了一個
??//?宏,#define??NO_PATH?0x00ffffff,如果圖中的兩個頂點之間的直接路徑的長度為
NO_PATH,
??//?表示圖中兩個頂點是不直接相通的。
??//
#ifndef?INCLUDE_SHORTESTPATH_H
#define?INCLUDE_SHORTESTPATH_H
#define?IN
#define?OUT
#define??NO_PATH?0x00ffffff
/*++
Abstract:
??該函數(shù)的功能是求得一個圖中的某個頂點到其他所有頂點的最短路經(jīng),及其最
短路經(jīng)的長度
??
Returen?value:
??類型是int,含義如下
??0 成功
??1???資源不夠
??
Examples:
??//你有一個圖的鄰接矩陣如AdjoinMatrix[n][n]和數(shù)組
Path[n],?Length[n](n為圖頂點的個數(shù),
??//然后你可以如下調(diào)用:ShortestPath(AdjoinMatrix,?
Length,?Path,?5,?0);
??//調(diào)用后,Path[n]中存放最短路徑,Length[n]中存放著最
短路徑的長度
??//下面的例子中我們求得從0頂點到其他定點的最短路經(jīng)及
其長度
??
float?AdjoinMatrix[5][5]=
{
{0, 10,NO_PATH,30,100},
{NO_PATH,0,50,NO_PATH,NO_PATH},
{NO_PATH,NO_PATH,0,NO_PATH,10},
{NO_PATH,NO_PATH,20,0,60},
{NO_PATH,NO_PATH,NO_PATH,NO_PATH,0}
};
int?Path[5];
float?Length[5];
??ShortestPath(AdjoinMatrix,?Length,?Path,?5,?
0);
??
int?i?=?0,?int?v?=0;
for(i?=?1;?i?<?5;?i++)
{
v?=?i;
while(v?!=?0)
{
printf("%d?",?v);
v?=?Path[v];
}
printf("%d\n",?v);
}
--*/
int?ShortestPath(
IN??float?**AdjoinMatrix, //存放圖的鄰接矩陣,是
一個二維數(shù)組
OUT?float?*Length, //用于返回到各
個點的最短路經(jīng)的長度
OUT?int???*Path, //用于返回最短
路經(jīng),Path[i]表示在最短路經(jīng)上頂點i前面的頂點
IN??int???VertexNum, //頂點的個數(shù)
IN??int???Vertex //起始頂點
);
#endif
??//
??//?ShortestPath.c?中實現(xiàn)了求一個圖中某個頂點到其他頂點的最短路經(jīng)的函數(shù)。
??//
#include?"ShortestPath.h"
#include?<stdlib.h>
/*++
Abstract:
該函數(shù)的功能是求得一個圖中的某個頂點到其他所有頂點的最短路經(jīng),及其最短
路經(jīng)的長度
Returen?value:
類型是int,含義如下
0 成功
1???資源不夠
--*/
int?ShortestPath(
IN??float?**AdjoinMatrix, //存放圖的鄰接矩陣,是
一個二維數(shù)組
OUT?float?*Length, //用于返回到各
個點的最短路經(jīng)的長度
OUT?int???*Path, //用于返回最短
路經(jīng),Path[i]表示在最短路經(jīng)上頂點i前面的頂點
IN??int???VertexNum, //頂點的個數(shù)
IN??int???Vertex //起始頂點
)
{
int?i?=?0,?j?=?0,?w?=?0;
//
//?已經(jīng)在最短路經(jīng)中的點的集合,如果VertexSet[i]不為0,則表示第
i個點在該集合中
//
int?*VertexSet?=?(int*)malloc(VertexNum);
if(VertexSet?==?NULL)
{
return?1; //缺乏內(nèi)存資源
}
//
//?初始化
//
for(i?=?0;?i?<?VertexNum;?i++)
{
Length[i]?=?*((float*)AdjoinMatrix?+?Vertex*VertexNum?
+?i);
VertexSet[i]=0;
if(i?!=?Vertex?&&?Length[i]?<?NO_PATH)
{
Path[i]=Vertex;
}
else
{
Path[i]?=?-1;
}
}
VertexSet[Vertex]?=?1;
Length[Vertex]?=?0;
//
//?求得最短路經(jīng)
//
for(i?=?0;?i?<?VertexNum-1;?i++)
{
float?min?=?NO_PATH;
int?u?=?Vertex;
for(j?=?0;?j?<?VertexNum;?j++)
{
if(?!VertexSet[j]?&&?Length[j]?<?min)
{
u?=?j;
min?=?Length[j];
}
}
VertexSet[u]?=?1;
for(w?=?0;?w?<?VertexNum;?w++)
{
if(!VertexSet[w]?&&?*((float*)AdjoinMatrix?+?
u*VertexNum?+?w)?<?NO_PATH?&&?Length[u]+*((float*)AdjoinMatrix?+?u*VertexNum?+?
w)?<?Length[w])
{
Length[w]?=?Length[u]?+?
*((float*)AdjoinMatrix?+?u*VertexNum?+?w);
Path[w]?=?u;
}
}
}
return?0;
}
總結
以上是生活随笔為你收集整理的如何将二维数组作为函数的参数传递的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 蓝桥杯 n进制小数
- 下一篇: ACRush 楼天城回忆录