- 浏览: 472825 次
- 性别:
- 来自: 南阳
文章分类
最新评论
-
yuanhongb:
这么说来,感觉CGI和现在的JSP或ASP技术有点像啊
cgi -
draem0507:
放假了还这么勤啊
JXL操作Excel -
chenjun1634:
学习中!!
PHP/Java Bridge -
Jelen_123:
好文章,给了我好大帮助!多谢!
hadoop安装配置 ubuntu9.10 hadoop0.20.2 -
lancezhcj:
一直用job
Oracle存储过程定时执行2种方法(转)
如何将二维数组作为函数的参数传递
作者: jatix
邮箱: jatix@163.com
QQ: 52287017
声明:
如果你是得道的大侠,这篇文章可能浪费你的时间,如果你坚持要看,我当然感觉很高
兴,但是希望你看完了别骂我!如果你发现我这篇文章有错误的话,你可以提出批评以及
指正,我将很乐意地接受。*_*
概述:
今天写程序的时候要用到二维数组作参数传给一个函数,我发现将二维数组作参数进行
传递还不是想象得那么简单里,但是最后我也解决了遇到的问题,所以这篇文章主要介绍
如何处理二维数组当作参数传递的情况,希望大家不至于再在这上面浪费时间。
正文:
首先,我引用了谭浩强先生编著的《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);
其实多维数组和二维数组原理是一样的,大家可以自己扩充的多维数组,这里不再赘述
。写到这里,我先向看了这篇文章后悔的人道歉,浪费你的时间了。下面是一个完整的例
子程序,这个例子程序的主要功能是求一个图中某个顶点到其他顶点的最短路经,图是以
邻接矩阵的形式存放的(也就是一个二维数组),其实这个函数也是挺有用的,但是我们这
篇文章的重点在于将二维数组作为函数的参数传递。
完整的例子程序包括三个文件,在Microsoft Visual C++ 6.0下调试通过。如下:
//
// mian.c 为主程序入口,并且调用了示范了如何调用求一个图中某个顶点到其他顶点
的最短路经
// 的函数
//
#include "short.h"
#include <stdio.h>
int main()
{
int i = 0, v = 0;
float AdjoinMatrix[5][5]=
{
{0, 10,NO_PATH,30,100},
{NO_PATH,0,50,NO_PATH,NO_PATH},
{NO_PATH,NO_PATH,0,NO_PATH,10},
{NO_PATH,NO_PATH,20,0,60},
{NO_PATH,NO_PATH,NO_PATH,NO_PATH,0}
};
int Path[5];
float Length[5];
ShortestPath(AdjoinMatrix, Length, Path, 5, 0);
for(i = 1; i < 5; i++)
{
v = i;
while(v != 0)
{
printf("%d ", v);
v = Path[v];
}
printf("%d\n", v);
}
return 0;
}
//
// ShortestPath.h 中定义了求一个图中某个顶点到其他顶点的最短路经的函数,还定
义了一个
// 宏,#define NO_PATH 0x00ffffff,如果图中的两个顶点之间的直接路径的长度为
NO_PATH,
// 表示图中两个顶点是不直接相通的。
//
#ifndef INCLUDE_SHORTESTPATH_H
#define INCLUDE_SHORTESTPATH_H
#define IN
#define OUT
#define NO_PATH 0x00ffffff
/*++
Abstract:
该函数的功能是求得一个图中的某个顶点到其他所有顶点的最短路经,及其最
短路经的长度
Returen value:
类型是int,含义如下
0 成功
1 资源不够
Examples:
//你有一个图的邻接矩阵如AdjoinMatrix[n][n]和数组
Path[n], Length[n](n为图顶点的个数,
//然后你可以如下调用:ShortestPath(AdjoinMatrix,
Length, Path, 5, 0);
//调用后,Path[n]中存放最短路径,Length[n]中存放着最
短路径的长度
//下面的例子中我们求得从0顶点到其他定点的最短路经及
其长度
float AdjoinMatrix[5][5]=
{
{0, 10,NO_PATH,30,100},
{NO_PATH,0,50,NO_PATH,NO_PATH},
{NO_PATH,NO_PATH,0,NO_PATH,10},
{NO_PATH,NO_PATH,20,0,60},
{NO_PATH,NO_PATH,NO_PATH,NO_PATH,0}
};
int Path[5];
float Length[5];
ShortestPath(AdjoinMatrix, Length, Path, 5,
0);
int i = 0, int v =0;
for(i = 1; i < 5; i++)
{
v = i;
while(v != 0)
{
printf("%d ", v);
v = Path[v];
}
printf("%d\n", v);
}
--*/
int ShortestPath(
IN float **AdjoinMatrix, //存放图的邻接矩阵,是
一个二维数组
OUT float *Length, //用于返回到各
个点的最短路经的长度
OUT int *Path, //用于返回最短
路经,Path[i]表示在最短路经上顶点i前面的顶点
IN int VertexNum, //顶点的个数
IN int Vertex //起始顶点
);
#endif
//
// ShortestPath.c 中实现了求一个图中某个顶点到其他顶点的最短路经的函数。
//
#include "ShortestPath.h"
#include <stdlib.h>
/*++
Abstract:
该函数的功能是求得一个图中的某个顶点到其他所有顶点的最短路经,及其最短
路经的长度
Returen value:
类型是int,含义如下
0 成功
1 资源不够
--*/
int ShortestPath(
IN float **AdjoinMatrix, //存放图的邻接矩阵,是
一个二维数组
OUT float *Length, //用于返回到各
个点的最短路经的长度
OUT int *Path, //用于返回最短
路经,Path[i]表示在最短路经上顶点i前面的顶点
IN int VertexNum, //顶点的个数
IN int Vertex //起始顶点
)
{
int i = 0, j = 0, w = 0;
//
// 已经在最短路经中的点的集合,如果VertexSet[i]不为0,则表示第
i个点在该集合中
//
int *VertexSet = (int*)malloc(VertexNum);
if(VertexSet == NULL)
{
return 1; //缺乏内存资源
}
//
// 初始化
//
for(i = 0; i < VertexNum; i++)
{
Length[i] = *((float*)AdjoinMatrix + Vertex*VertexNum
+ i);
VertexSet[i]=0;
if(i != Vertex && Length[i] < NO_PATH)
{
Path[i]=Vertex;
}
else
{
Path[i] = -1;
}
}
VertexSet[Vertex] = 1;
Length[Vertex] = 0;
//
// 求得最短路经
//
for(i = 0; i < VertexNum-1; i++)
{
float min = NO_PATH;
int u = Vertex;
for(j = 0; j < VertexNum; j++)
{
if( !VertexSet[j] && Length[j] < min)
{
u = j;
min = Length[j];
}
}
VertexSet[u] = 1;
for(w = 0; w < VertexNum; w++)
{
if(!VertexSet[w] && *((float*)AdjoinMatrix +
u*VertexNum + w) < NO_PATH && Length[u]+*((float*)AdjoinMatrix + u*VertexNum +
w) < Length[w])
{
Length[w] = Length[u] +
*((float*)AdjoinMatrix + u*VertexNum + w);
Path[w] = u;
}
}
}
return 0;
}
发表评论
-
Java调用WebService(axis2)两种方法
2014-08-06 17:37 1507方式一:生成客户端代码调用方式。 通过插件工具生成客户端代码 ... -
java中string与byte[]的转换
2013-01-30 17:16 13481.string 转 byte[] byte[] midb ... -
JXL操作Excel
2013-01-05 18:23 792jxl是一个韩国人写的java操作excel的工具, 在开 ... -
java dom4j操作xml
2012-09-01 19:48 990SAXReader reader = new SAXReade ... -
Oracle BIEE在linux下的安装
2012-04-19 00:02 2827BIEE在RHEL 4.x平台安装手册 系统环境:Red H ... -
Hadoop 开发平台搭建
2011-11-15 17:54 958【安装JDK】 首先,从http://www.oracl ... -
hadoop 命令手册
2011-11-15 17:52 788概述 所有的hadoop命令均由bin/hadoop脚本 ... -
Hadoop0.20.2版本在Ubuntu10下安装和配置
2011-11-08 15:44 8681、安装JDK (1)下载安装JDK:确保计算机联网之后命令 ... -
用 Linux 和 Apache Hadoop 进行云计算
2011-11-08 15:03 889本文内容包括: 云计 ... -
hadoop安装配置 ubuntu9.10 hadoop0.20.2
2011-11-08 14:54 1151Hadoop是一个易于安装易于使用的系统,他既适用于云计算的新 ... -
firefox浏览shtml时直接显示源代码问题
2008-11-06 20:01 3250firefox浏览shtml时直接显 ... -
java读xml
2008-09-19 13:55 3043java 读xml文件例子 xml文件: <?xml ... -
java 生成 ip地址
2007-12-10 16:55 5005在TCP/IP 互联网时,经常会需要查询自己主机的IP地址和w ... -
java生成exe
2007-11-23 11:51 4604这个是borland不公开的使用技巧,能够通过jbuild ... -
java map 介绍
2007-11-03 15:52 2770Java Map 集合类简介 作者 ... -
java循环示例集锦
2007-11-03 14:37 34641、 /* * Created on 2004-8-22 * ... -
java中读取sql server数据库空字段异常的bug
2007-10-19 20:33 1499这两天一直被一个问题困扰许久,自己的数据库查询中老是报异常 ... -
servlet及jsp中的多线程同步问题
2007-10-19 19:15 1269Servlet/JSP技术和ASP、PHP等相比,由于其多线程 ... -
hibernate学习指导(转)
2007-09-26 14:01 1442Hibernate入门容易,掌握 ... -
session笔记(转)
2007-09-26 13:36 1070目录: 一、术语session ...
相关推荐
主要给大家介绍了关于C语言中二维数组作为函数参数来传递的三种方法,文中通过示例代码介绍的非常详细,对大家学习或者使用C语言有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
实现数组的行列互换 形参使用二维数组。函数调用使用引用传递,比较基础。
形式参数:是一个变量,用于存储调用函数时传递给函数的实际参数。 实际参数:传递给形式参数的具体数值。 return:用于结束函数。 返回值:该函数运算后的结果,该结果会返回给调用者。 函数的特点 ...
注意:函数模板maxMin中要处理二维数组A的m行n列的诸元素,但设计第一参数传递过来的是Type*类型的首元素指针,所以具体处理时可以按照如下的“一维数组”方式来进行(共处理m乘以n个数据 -- 也即二维数组A的m行n列...
将二维数组传递给本函数,本函数会将数组显示为图像。注意数组传递前需先转换为char型。 图像显示是windows编程的基础,本程序可作为一个子函数用于调用,可同时显示多张图像。
我定义了这样一个数组,我想把这个数组作为参数,传递到一个函数中,并要在函数中能引用该二维数组的元素,我该怎么做? 第一种方式是直接传递二维数组,但是必须标明第二维的值,因为如果只是传递a[][],编译器...
创建任何二维数组,调用snail函数,并将其传递给二维数组。 输入 let array = [ [ 1 , 2 , 3 , 1 ] , [ 4 , 5 , 6 , 4 ] , [ 7 , 8 , 9 , 7 ] , [ 7 , 8 , 9 , 7 ] ] console . log ( snail ( array ) ) ; 输出 [ 1 ...
C++中指针指向二维数组实例详解 一维指针通常用指针表示,其指向的地址是数组第一元素所在的内存地址,如下 int ary[4][5]; int(*aryp)[5] = ary; 那么ary[4]相当于int(*aryp),以下理解如此,但参数传递需要知道...
多维数组名作为函数参数传递:在二维数组中,数组名a是指向首行a[0]的指针,也就是说a=&a[0]; a[0]是指向首元素a[0][0]的指针,也就是说a[0]=&a[0][0]
输入5个学生,4门课成绩,二维数组stu[5][4]表示,行标表示学生,列标表示课程成绩,分别编写函数aver()、fals()和well()完成:(1)求第一门课的平均分;(2)统计有2门以上课程不及格的同学人数;(3)平均成绩在90分...
1.掌握函数的定义和使用方法;掌握函数调用的方法;掌握函数参数传递的机制;...2.熟练掌握一维数组和二维数组的定义、引用和初始化;掌握字符数组与字符串的关系以及字符串变量的表示,熟练字符串处理函数的应用。
6.2.2怎样引用二维数组的元素151 6.2.3二维数组的初始化152 6.2.4二维数组程序举例153 6.3字符数组155 6.3.1怎样定义字符数组155 6.3.2字符数组的初始化156 6.3.3怎样引用字符数组中的元素156 6.3.4字符串和字符串...
6.2.2怎样引用二维数组的元素 6.2.3二维数组的初始化 6.2.4二维数组程序举例 6.3.字符数组 6.3.1怎样定义字符数组 6.3.2字符数组的初始化 6.3.3怎样引用字符数组中的元素 6.3.4字符串和字符串结束标志...
一维指针其实就相当于一维数组,不用去看书上所说的数组在内存中的首地址这些晦涩的话,以此类推 二维指针就相当于二维数组,新手对一维数组的开辟与释放比较容易熟悉,例如上面的a 释放就是 delete []a;...
二维数组的定义和使用;字符数组和字符串;常 用字符串处理函数的使用。 4.函数:常用库函数的正确调用;函数的定义;函数参数传递和返回值的含义;函 数的调用;函数的嵌套调用和递归调用;数组作为函数参数;局部...
(31)二维数组应用实例(2) (32)用一维数组来存储字符串 (33)字符串的输入与输出 (34)字符串数组 (35)用于字符串处理的函数 (36)字符串应用实例 (37)传给Main函数的参数 (38)函数指针 (39)函数的递归调用 (40)变量作用...
如要将二维数组赋给一指针,应这样赋值: int a[3][4]; int (*p)[4]; //该语句是定义一个数组指针,指向含4个元素的一维数组。 p=a; //将该二维数组的首地址赋给p,也就是a[0]或&a[0][0] p++; //该语句执行过后,...