转:如何将二维数组作为函数的参数传递

来源:互联网 发布:变女声声音软件 编辑:程序博客网 时间:2024/05/22 02:09

如何将二维数组作为函数的参数传递

今天写程序的时候要用到二维数组作参数传给一个函数,我发现将二维数组作参数进行传递还不是想象得那么简单里,但是最后我也解决了遇到的问题,所以这篇文章主要介绍如何处理二维数组当作参数传递的情况,希望大家不至于再在这上面浪费时间。

正文:

 

首先,我引用了谭浩强先生编著的《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);

其实多维数组和二维数组原理是一样的,大家可以自己扩充的多维数组,这里不再赘述。写到这里,我先向看了这篇文章后悔的人道歉,浪费你的时间了。下面是一个完整的例子程序,这个例子程序的主要功能是求一个图中某个顶点到其他顶点的最短路经,图是以邻接矩阵的形式存放的(也就是一个二维数组),其实这个函数也是挺有用的,但是我们这篇文章的重点在于将二维数组作为函数的参数传递。


发表于 @ 2006年07月14日 10:39:00 | 评论( 10 ) | 编辑| 举报| 收藏

旧一篇:路由器原理和路由协议、算法详解 | 新一篇:Dijkstra算法的C++实现
查看最新精华文章 请访问博客首页相关文章
如何将二维数组作为函数的参数传递如何将二维数组作为函数的参数传递和我一起写矩阵类(三)如何将二维数组作为函数的参数传递精通C语言4-一维或多维数组作为函数参数的问题二维数组名作为实参或者形参如何将二维数组作为函数的参数传递如何将二维数组作为函数的参数传递tolm02 发表于2006年9月29日 14:43:00 IP:举报回复删除
很好!谢谢了!pengkejifo 发表于2009年1月12日 16:29:57 IP:举报回复删除
在网上搜索了很多,没有一个看得懂的,而且都不符合自己的要求,到您这里一看,马上实验了下,问题迎刃而解,非常感谢!(PS:百度搜索不到这,从GOOGLE过来的,哎)pengkejifo 发表于2009年1月12日 16:30:03 IP:举报回复删除
在网上搜索了很多,没有一个看得懂的,而且都不符合自己的要求,到您这里一看,马上实验了下,问题迎刃而解,非常感谢!(PS:百度搜索不到这,从GOOGLE过来的,哎)lihailinlihailin 发表于2009年5月31日 18:49:58 IP:举报回复删除
谢了zhengxiujuan 发表于2009年9月28日 9:26:00 IP:举报回复删除
受益啦~~匿名用户 发表于2010年4月4日 10:48:30 IP:举报回复删除
很好匿名用户 发表于2010年4月4日 10:49:40 IP:举报回复删除
比起其他的垃圾文章,这算是绝版美文了。

asiainfolf 发表于2010年6月14日 13:08:41 IP:举报回复删除
Func((int**)a, 3, 3); 本文精华,可以用这一句概括吧 asiainfolf 发表于2010年6月14日 13:11:20 IP:举报回复删除
*((int*)array + n*i + j); 这句也挺不错 asiainfolf 发表于2010年6月14日 13:11:57 IP:举报回复删除
void Func(int **array, int m, int n); 凑三个吧,功德圆满啦 发表评论

原创粉丝点击