二維數組的傳參數的方法

 

如何將二維數組做爲函數的參數傳遞ios

  今天寫程序的時候要用到二維數組做參數傳給一個函數,我發現將二維數組做參數進行傳遞還不是想象得那麼簡單裏,可是最後我也解決了遇到的問題,因此這篇文章主要介紹如何處理二維數組看成參數傳遞的狀況,但願你們不至於再在這上面浪費時間。數組

正文:函數

 

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

將二維數組做爲參數傳遞,原文以下(略有改變,請原諒):設計

 

  [原文開始]指針

    能夠用二維數組名做爲實參或者形參,在被調用函數中對形參數組定義時能夠指定全部維數的大小,也能夠省略第一維的大小說明,如:blog

    void Func(int array[3][10]);內存

    void Func(int array[][10]);編譯器

    兩者都是合法並且等價,可是不能把第二維或者更高維的大小省略,以下面的定義是不合法的:io

    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;
}
相關文章
相關標籤/搜索