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

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

正文:

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

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

//二维数组传参问题示例
#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;
}

  

转载于:https://www.cnblogs.com/aTianTianTianLan/p/4219917.html

二维数组的传参数的方法相关推荐

  1. C/C++ 一维数组的传参/一级指针的传参 二维数组的传参/二级指针的传参 三维数组的传参/三级指针的传参 方法总结分析终极篇

    序 最近复习c/c++数组的传参,发现了一些问题,下面是一些总结和思考 正文 一维数组的传参/一级指针的传参/普通指针 在理解指针的基础上,一维数组的指针传递很简单,我们知道数组的数组名就是这个数组首 ...

  2. c/c++ 一维数组、二维数组作为函数参数、返回值

    c/c++ 一维数组.二维数组作为函数参数.返回值 一.一维数组作为参数 传入数组 int [] 为了规范,常常需要将数组的size一同传入,这是因为C++/C遇到参数为数组时,不会去一个个拷贝数组内 ...

  3. 二维数组的传参调用写法

    初遇二维数组作函数参数,宛如自己化身为了大头儿子.很头大. 不禁大声呐喊:该怎么声明定义,该怎么调用,又该怎么函数中操作元素和地址? 在此,我要拨开这些问题的一些迷雾. 我相信,有心人看完后,再遇就不 ...

  4. C语言 | 二维数组作为函数参数

    1024G 嵌入式资源大放送!包括但不限于C/C++.单片机.Linux等.关注微信公众号[嵌入式大杂烩],回复1024,即可免费获取! 偶然间发现C语言二维数组作为函数的参数是个比较容易出错的问题. ...

  5. C++二维数组做函数参数

    C++二维数组做函数参数 二维数组做函数参数的形式主要有: /对于一个m行n列int元素的二维数组 //函数f的形参形式 f(int daytab[m][n]) {...}//以下两种可以忽略行数 f ...

  6. 二维数组作为函数参数的用法(c++)

    背景 今天刷题的时候遇到了需要一个大小可变的二维数组作为函数参数进行传递的情况,有点模糊不清,所以查了一些资料,写了这篇博客. 大小固定的二维数组 正确写法如下: void Func(int arra ...

  7. C-指针,二级指针,二维数组作为函数参数使用,C语言链表(详解)

    一级指针 int *p;            //表示定义一个int型(4字节)的指针p &p                 //表示p自身的地址位置 p                  ...

  8. C语言二维数组元素的多种表示方法小结

    C语言二维数组元素的多种表示方法小结 昨天,一个小可爱问我,为何函数中,数组可以改变主函数中的值,比如b[i],就可以改原来数组中的值.其实b[i] 等价于 *(b + i)也是通过地址间接更改的,小 ...

  9. C语言 二维数组做函数参数的几种情况

    (1)       实参为数组元素地址,虚参为元素类型指针 (a)       调用函数:fun(*a,3*4);  //*a也可为a[0] or &a[0][0] 函数: fun(int * ...

最新文章

  1. 第十一周编程总结--助教
  2. 友盟-上传开发发布证书
  3. 解决django配合nginx部署后admin样式丢失
  4. redis mysql 解决超卖_Redis 分布式锁解决超卖问题
  5. 3.Android 优化布局(解决TextView布局)
  6. .net core 实现基于 cron 表达式的任务调度
  7. linux服务器和客户端配置,Linux基础教程:YUM服务端与客户端配置步骤
  8. 金色传说:SAP-BC-下载数据及导入,导出EXCEL文件的控制问题
  9. 在腾讯实习的那段日子:不要在难受的时候选择 '逃避/离开'
  10. ubuntu下查看USB摄像头参数以及摄像头测试
  11. 用Python学《微积分B》(Fourier级数)
  12. 如何修改文件的编码格式
  13. 4选1数据选择器程序及testbench文件,给出仿真波形,分析
  14. MySQL(六):InnoDB数据文件
  15. YTU OJ-1329: 手机尾号评分
  16. 古籍研究社系列第6部《迟来的翅膀》读后感……吗?
  17. 计算机组老师颁奖词,学生表彰颁奖词与学生计算机室管理制度合集.doc
  18. Visual Studio Code,一款功能强大且轻巧的免费代码集成编辑器介绍
  19. 机器学习指南_机器学习项目的研究指南
  20. 一个数加100是完全平方数,再加168又是一个完全平方数

热门文章

  1. 从0开始学习GitHub系列之「认识并加入GitHub」
  2. 如何让Ubuntu系统支持WebP图片格式
  3. RPA女子计划—面向日本女性的工作方式改革
  4. 模态框之Uncaught Error: Syntax error, unrecognized expression:
  5. 关于Swift4.0 Method Swizzling(iOS的hook机制)使用
  6. wordpress 分类使用不同的模版
  7. 度量.net framework 迁移到.net core的工作量
  8. 配置FTP服务(一):pureftp部署和优化
  9. 为什么对象字面量没有名字?
  10. 《信息系统项目管理师软考辅导——3年真题详解与全真模拟》主要创新点、关注点...