版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、前几日用C编写DSP程序时,遇到一个问题:如何向C函数中传递指向二维数组的指针参数。初接触以为很简单,直接声明一个二维数组,然后把数组名传进去。但是一经编译便报错。后来仔细想了一下,并查找了一些相关资料,发现二维数组在概念上远比一维数组复杂,或者说二维数组以一种晦涩的方式构建在一维数组之上。 先来回顾一下一维数组。一维数组的数组名即为指向该数组的指针,该指针值保存了数组存放在内存中的一块连续区域的起始地址;数组的下标表示了这片内存区域的某存储区相对于起始地址的偏移量。简单来讲就是:指向一维数组的指针,指向数据存放区域的起始位置。 事实上,计算机系统的多维数组其实最终还是以一维数组的形式实现的。
2、就N x M的二维数组来讲,设其数组名为array。指针array指向一个数组,该数组存放的是一系列指针,这些指针分别指向相应的一维数组,而这些数组中存放的才是我们的数据。 array -> 一维数组指针1 -> 一维数组,M长 一维数组指针2 -> 一维数组,M长 一维数组指针N -> 一维数组,M长 由此array是第i个指针变量地址,array
3、j则表示相对于第i个指针变量偏移j*sizeof(数组类型)。系统通过这种机制访问了该二维数组的第i行,第j列的内容。 有上述可知,指向二维数组的指针其实是指向“指针变量地址”的指针变量。所以在声明指向二维数组的指针时,用 int * array的形式。 有以下两种方式来对二维数组分配内存:/ 方法一 #include <stdlib.h> / 必须包含该头文件,里面定义了malloc的实现 int * array = malloc( N * sizeof(int *) ); &
4、#160; for (int k=0;k<N;k+) arrayk = malloc( M * sizeof(int) ); / 方法二 #include <stdlib.h> int * array = malloc( N * sizeof(int *) ); array0 = malloc( M * sizeof(int) ); for (int k=1;k<N;k+)
5、arrayk = array0+M*k; 上述两种方法的区别在于:前者在内存中分配的区域有可能是不连续的;而后者则在内存中的一片连续区域为该数组分配空间。 我们还可以通过一维数组模拟二维数组。在这中间要进行下标转换。如对于模拟的NxM数组,访问其第i行,第j列元素时,在一维数组中对应的位置是i*M+j。当然为了更简捷,我们可以把这个数组下标转换过程定义为一个宏,交由编译系统来处理。 #define Arr2 ( array_name, row,col ) array_namerow*M+col
6、; 定义该宏后,访问Arr2( array, i, j)等价于访问 arrayi*M+j。今天写程序的时候要用到二维数组作参数传给一个函数,我发现将二维数组作参数进行 传递还不是想象得那么简单里,但是最后我也解决了遇到的问题,所以这篇文章主要介绍 如何处理二维数组当作参数传递的情况,希望大家不至于再在这上面浪费时间。 正文: 首先,
7、我引用了谭浩强先生编著的C程序设计上面的一节原文,它简要介绍了如何 将二维数组作为参数传递,原文如下(略有改变,请原谅): 原文开始 可以用二维数组名作为实参或者形参,在被调用函数中对形参数组定义时可以可以指 定所有维数的大小,也可以省略第一维的大小说明,如: &
8、#160; void Func(int array310); void Func(int array10); 二者都是合法而且等价,但是不能把第二维或者更高维的大小省略,如下面的定义是 不合法的:
9、; void Func(int array); 因为从实参传递来的是数组的起始地址,在内存中按数组排列规则存放(按行存放), 而并不区分行和列,如果在形参中不说明列数,则系统无法决定应为多少行多少列,不能 只指定一维而不指定第二维,下面写法是错误的: void Func(int
10、 array3);实参数组维数可以大于形参数组,例如实参数组定义为 : void Func(int array310); 而形参数组定义为: int array510;
11、; 这时形参数组只取实参数组的一部分,其余部分不起作用。 原文结束 大家可以看到,将二维数组当作参数的时候,必须指明所有维数大小或者省略第一维的 ,但是不能省略第二维或者更高维的大小,这是由编译器原理限制的。大家在学编译原理 这么课程的时候知道编译器是这样处理数组的:
12、0; 对于数组 int pmn; 如果要取pij的值(i>=0 && i<m && 0<=j && j < n),编译器是这样寻址的,它的 地址为: p +
13、60; i*n + j; 从以上可以看出,如果我们省略了第二维或者更高维的大小,编译器将不知道如何正确 的寻址。但是我们在编写程序的时候却需要用到各个维数都不固定的二维数组作为参数, 这就难办了,编译器不能识别阿,怎么办呢?不要着急,编译器虽然不能识别,但是我们 完全可以不把它当作一个二维数组,而是把它当作一个普通的指
14、针,再另外加上两个参数 指明各个维数,然后我们为二维数组手工寻址,这样就达到了将二维数组作为函数的参数 传递的目的,根据这个思想,我们可以把维数固定的参数变为维数随即的参数,例如: void Func(int array310); void
15、0; Func(int array10); 变为: void Func(int *array, int m, int n); 在转变后的函数中,arrayij这样的式子是不对的(不信,大家可以试一下),因为 编译器不能正确
16、的为它寻址,所以我们需要模仿编译器的行为把arrayij这样的式子 手工转变为 *(int*)array + n*i + j); 在调用这样的函数的时候,需要注意一下,如下面的例子:
17、; int a33 = 1, 1, 1, 2, 2, 2, 3, 3, 3 ;
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 安徽xx工业废盐资源化利用项目可行性研究报告
- 电力系统网络视频集中监控解决方案
- 风力发电站运营与管理培训
- 电力系统建模与仿真
- Naftypramide-DA-992-生命科学试剂-MCE
- MRX-2843-hydrochloride-UNC2371-hydrochloride-生命科学试剂-MCE
- minus-BO-2367-生命科学试剂-MCE
- Methyl-2-6-bromo-1H-indol-3-yl-acetate-生命科学试剂-MCE
- MDK0734-生命科学试剂-MCE
- Lipid-B37-生命科学试剂-MCE
- 《中国传统文化》课件模板(六套)
- 第24课《寓言四则》说课稿 2024-2025学年统编版语文七年级上册
- 色卡-CBCC中国建筑标准色卡(千色卡1026色)
- 2024-2030年中国水产养殖行业发展形势及投资风险分析报告
- GB/T 42125.1-2024测量、控制和实验室用电气设备的安全要求第1部分:通用要求
- 采购部门年终总结报告
- 蓝精灵课件教学课件
- 2024年河北省高考历史试卷(含答案解析)
- 译林三起小学英语六年级上册期末复习补全对话短文专题练习一附答案解析
- 泵站工程设计(共138张课件)
- 2024秋期河南开放大学本科《法律社会学》一平台无纸化考试(作业练习1至3+我要考试)试题及答案
评论
0/150
提交评论