二维数组作为参数递(用二维数组处理矩阵),但是希望接受二维数组参数的函数可以处理任意维度的数组(希望矩阵的行数和列数都是不固定的)。

----------------------------------------------------------------------------------------------
但一般二维数组的基本规则好像是这样的:可以用二维数组名作为实参或者形参,在被调用函数中对形参数组定义时可以可以指定所有维数的大小,也可以省略第一维的大小说明。如:

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

二者都是合法而且等价,但是不能把第二维或者更高维的大小省略,如下面的定义是不合法的:
    void Func(int array[][]);

二维数组当作参数的时候,必须指明所有维数大小或者省略第一维的,但是不能省略第二维或者更高维的大小,这是由编译器原理限制的。在学编译原理这么课程的时候知道编译器是这样处理数组的:
对于数组 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] = 
    {
      {1, 1, 1},
      {2, 2, 2},
      {3, 3, 3}
    };
    Func(a, 3, 3);

根据不同编译器不同的设置,可能出现warning 或者error,可以进行强制转换如下调用:  
    Func((int**)a, 3, 3);
----------------------------------------------------------------------------------------------

需要(int**)的强制转换,是因为二维数组和二级指针是不同的,a实质上是一个int (*a)[3],它是一个数组指针,即a[0]是第一维数组的首个元素的地址,a[1]是第二维数组的首个元素的地址,a[2]是第三维数组的首个元素的地址,与int**是不同的类型;如果转为int**,就失去了像数组指针那样a + i = a + i*3的效果了
而如果又定义一个char *p[3],它是一个一维的指针数组,此时p是指向了一个指针,而不是数组。那么这时如果定义char **q = p,就是可以的,而且可以通过q[0],q[1]来访问字符串。

数组和指针这种东西真是太繁琐复杂了,个人愚见,在C++里就尽量使用STL,并且可以用模板的非类型形参来解决这种灵活处理不固定行列数矩阵的函数,Effective C++里面应该有介绍,并且有对这种模板的优化。

C/C++如何传递二维数组?的更多相关文章

  1. C/C++怎样传递二维数组,转载自CSDN

    用二维数组作为参数传递(用二维数组处理矩阵),但是希望接受传递二维数组参数的函数可以处理任意维度的数组(希望矩阵的行数和列数都是不固定的). [以下转帖] ---------------------- ...

  2. 如何在C中传递二维数组作为参数?

    回答: 在C语言中,有很多方法可以将2d数组作为参数传递.在下面的部分中,我描述了将2d数组作为参数传递给函数的几种方法. 使用指针传递2d数组以在c中运行 多维数组的第一个元素是另一个数组,所以在这 ...

  3. C语言传递二维数组

    方法一, 形参给出第二维的长度. 例如: #include <stdio.h> ] ) { int i; ; i < n; i++) printf("/nstr[%d] = ...

  4. c++ 二维数组传递

    c++ 二维数组传递 我们在传递二维数组时,对于新手来说,可能会存在某些问题,下面讲解几种传递方法 在讲解如何传递二维数组时,先看看如何动态new 二维数组 // 二维数组动态申请 int row , ...

  5. C语言中将二维数组作为函数参数来传递

    c语言中经常需要通过函数传递二维数组,有三种方法可以实现,如下: 方法一, 形参给出第二维的长度. 例如: #include <stdio.h> void func(int n, char ...

  6. c指针与数组,传参问题,指针数组与数组指针的区别,二维数组动态内存分配

    一 数组的结构:顺序存储,看谭浩强中的图,牢记 1.数组名指代一种数据结构:数组 现在可以解释为什么第1个程序第6行的输出为10的问题,根据结论1,数组名str的内涵为一种数据结构,即一个长度为10的 ...

  7. nRF51800 蓝牙学习 进程记录 2:关于二维数组 执念执战

    前天在玩OLED时想完成一直想弄得一个东西,就是简单的单片机游戏.因为STM32和nRF51822的内存足够,所以就用缓存数组的方法来显示图像(我也不知道术语是啥,反正就是在内存中建立一个128X64 ...

  8. 二维数组中的查找问题--剑指offer面试题3

    题目:在一个二维数组中,对每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. // 二维数组中的查找 ...

  9. C++二维数组讲解、二维数组的声明和初始化

    我们知道,一维空间是一条线,数学中用一条数轴来表达:二维空间是一个平面,数学中用平面坐标系来表达.那么二维数组又是什么样的呢? 线与面 我们用一个下标来描述一维数组中的某个元素,就好像在用数描述一条线 ...

随机推荐

  1. 解决sofaboot项目右键入口方法没有run sofa application

    选中入口方法名,右键出现run sofa application

  2. Java实现导出Excel

    项目中实现的代码: 一.//controller @RequestMapping(value = "/exportAccountManager") public void expo ...

  3. 搭建http文件服务器 - python3使用http.server搭建http文件服务器

    适用场景 只要有python3就可以,windows系统cmd窗口直接敲命令,Linux系统,直接敲命令 step-1 cd cd 到需要搭建服务器的目录 step-2 http.server pyt ...

  4. 常用的ppt技巧

    取色器 对齐 形状使用

  5. chrome 的手机调试工具 toggle device toolbar

    chrome 的手机调试工具 toggle device toolbar 是否可以模拟到不同系统,如苹果系统和安卓系统.

  6. 《如何进行接口mock测试》

    前言: Mock通常是指:在测试一个对象时,我们构造一些假的对象来模拟与其交互.而这些Mock对象的行为是我们事先设定且符合预期.通过这些Mock对象来测试对象在正常逻辑,异常逻辑或压力情况下工作是否 ...

  7. 1.3redis小结--配置php reids拓展

    1.执行php文件 输出phpinfo();  <?php phpinfo(); 2.根据PHPinfo的信息确定需要下载的 php_redis.dll , php_igbinary.dll 版 ...

  8. [转载]Nginx负载均衡配置实例详解

    负载均衡是我们大流量网站要做的一个东西,下面我来给大家介绍在Nginx服务器上进行负载均衡配置方法,希望对有需要的同学有所帮助哦. 负载均衡 先来简单了解一下什么是负载均衡,单从字面上的意思来理解就可 ...

  9. list集合根据字段分组统计转换成map

    前言 表格需要对数据进行统计 代码实现 public Map getUnitStoreSum(String unitId, String billCode) { List store=listUnit ...

  10. Java面向对象编程(三)

    static关键词 static关键字:可以修饰属性.方法.代码块.内部类. 一.使用static修饰属性:静态变量(或类变量) 1. 属性,按是否使用static修饰,又分为:静态属性 vs 非静态 ...