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

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

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<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);
----------------------------------------------------------------------------------------------

需要(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++里面应该有介绍,并且有对这种模板的优化。

 

最新文章

  1. easyUI-combobox 动态绑定数据源
  2. 关于ssh上传文件
  3. 大型网站演化(转载 http://homeway.me/2014/12/10/think-about-distributed-clusters/)
  4. 关掉apache2服务器日志文件
  5. 【python3】collections系列介绍
  6. js实现图片预显示
  7. 75. Sort Colors
  8. CodeSmith datagridview属性
  9. javascript 关于闭包的知识点
  10. C#计算两个文件的相对目录算法
  11. RabbitMQ入门-初识RabbitMQ
  12. 201521123005《java程序设计》第五周学习总结
  13. DAY4-打卡第四天-2018-1-12
  14. Http的会话跟踪和跨站攻击(xss)
  15. 详细的&lt;select&gt;下拉列表详解
  16. jQuery(七)、效果和动画
  17. 详解volatile 关键字与内存可见性
  18. (N叉树 递归) leetcode 590. N-ary Tree Postorder Traversal
  19. Delphi中Move、CopyMemory操作
  20. ruby module extend self vs module_funciton

热门文章

  1. WPF中窗体在同一个位置实现不同页面切换
  2. python 基础之运算符
  3. 转 在Qt中用QAxObject来操作Excel
  4. C++值传递、引用传递和指针传递
  5. bootstrap历练实例:标签式的导航菜单
  6. 关于Java IO流学习总结
  7. Codeforces Round #477滚粗记&amp;&amp;祭第一次div2场
  8. (29)zabbix执行远程命令
  9. linux运维中常用的指令
  10. SpringMVC之HandlerAdapter执行流程