二维数组的传参数的方法

 

如何将二维数组做为函数的参数传递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;
}
相关文章
相关标签/搜索