原文地址:http://blog.csdn.net/xuleicsu/article/details/919801


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

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

正文:

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

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

C++怎么用二维数组作为形参传入的更多相关文章

  1. 【C语言】二维数组做形参

    二维数组有两种形式: ①在栈上:         int a[4][4] = {...}; ②在堆堆上:          int ** a = new int *[4];           for ...

  2. C++ 二维数组作为形参传递使用实例

    在线代码编辑器: http://codepad.org/ 1.*指针 void display(int *arr, const int row, const int col) { ; i < r ...

  3. 题目一:使用Java实现二维数组中的查找

    考点:数组       题目:二维数组中的查找   描述:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判 ...

  4. C++ 二维数组(双重指针作为函数参数)

    本文的学习内容参考:http://blog.csdn.net/yunyun1886358/article/details/5659851 http://blog.csdn.net/xudongdong ...

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

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

  6. C++中用二维数组传参时形参该怎样写[转]

    二维数组的存储方式是和一维数组没什么区别,但是用二维数组做参数,它的形参该怎样写? 要注意的是:函数中的形参其实就相当于一个声明,并不产生内存分配,形参的目的就是要让编译器知道函数参数的数据类型. 正 ...

  7. 计算机二级-C语言-对二维数组数据进行处理。对文件进行数据输入。形参与实参。

    //函数fun的功能为:计算x所指数组中N个数的平均值(规定所有数都为正数),平均值通过形参返回给主函数,将小于平均值且最接近平均值的数作为函数值返回,并输出. //重难点:形参与实参之间,是否进行了 ...

  8. c++ 二维数组传递

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

  9. 【C语言】二维指针做形参

    转自:http://hi.baidu.com/gpmzccqceabimqq/item/f499f057aa1520404eff208b 关键: 传入时强制类型转换 + 使用时自己手工寻址 今天写程序 ...

随机推荐

  1. cf 786 B 线段树优化建图

    cf 786 B 链接 CF 思路 n个点,3种建边方式,规模\(O(n^2)\) 线段树优化建图 注意 读入的数据好坑啊,说好的v,u变成了u,v. 两棵树,一棵出,一棵入.线段树的作用只不过是按照 ...

  2. 【转】android Looper 理解

    在主线程中运行的部分,都可以直接使用Handler,因为在主线程启动的过程中(ActivityThread的main函数里)会调用Looper.prepareMainLooper(),Looper类中 ...

  3. stixel-net绘制指标图

    需解决问题: 1.离散点进行平滑曲线画法 https://blog.csdn.net/cdqn10086/article/details/70143616 def draw_curve(x,y,img ...

  4. Spring Boot 推荐的基础 POM 文件

    名称 说明 spring-boot-starter 核心 POM,包含自动配置支持.日志库和对 YAML 配置文件的支持. spring-boot-starter-amqp 通过 spring-rab ...

  5. 【luogu P3369 【模板】普通平衡树(Treap/SBT)】 题解 pb_ds

    我永远都爱STL ! 我爱PB_DS ! #include <iostream> #include <cstdio> #include <ext/pb_ds/tree_p ...

  6. window与MAC,多台机器ssh免密码登录同一台机器执行某个脚本,

    参考:https://zhidao.baidu.com/question/586579720.html A B C三台机器上以当前用户运行如下命令生成本主机的公钥和私钥文件: 1 ssh-keygen ...

  7. SpringBoot学习17:springboot热部署配置

    spring为开发者提供了一个名为spring-boot-devtools的模块来使Spring Boot应用支持热部署,提高开发者的开发效率,无需手动重启Spring Boot应用. devtool ...

  8. 关于Vue-cli 跨域,即使是非自己的服务器也可以get到内容

    刚入门vue ,打算用vue的脚手架做一个小项目.需要用到第三方的api,无奈遇到各种各样的问题. 比如 Access-Control-Allow-Origin ,或者使用了ajax的jsonp模式之 ...

  9. code ELIFECYCLE (代码周期)

    问题:build 不成功 解决:新建一个dist 文件,没有自动新建dist 文件 问题 :npm run dev 时候 解决:

  10. 2018 Wannafly summer camp Day2--Utawarerumono

    Utawarerumono 描述 题目描述: 算术是为数不多的会让久远感到棘手的事情.通常她会找哈克帮忙,但是哈克已经被她派去买东西了.于是她向你寻求帮助. 给出一个关于变量x,y的不定方程ax+by ...