这个我也知道,问题是我怎么改都不对,要不我也不会到这来问了。您有没有源码示例一下?谢谢!
这样很死板,我想写个通用点的,因为我的二维数组维数在变化,尤其是最后一个维度在变化。如果在子函数的形参中固定了最后一个维度的话,就没有任何灵活性了。我给子函数传了数组的首地址,然后在子函数中用一维数组的形式赋值(我主要是想赋值),但是在主函数中调用数组时值不对,也就是说值并没有被修改,不是说二维数组在内存中也是按列排列的么?难道在子函数中这个列就不管用了?
追答 如果用二维数组,以上用指针实现的过程中把维数设成变量就可以了,但是这样初始化时稍微有点儿麻烦。
还有一种做法,就是使用一维数组来存储二维数据的值,比如把int a[5][10]转换为int a[50],在读取时进行坐标转换,效果也是一样的,如:
int getelement(int *a, int i, int j)
{
return a[i*10+j];
}
void setelement(int *a, int i, int j, int value)
{
a[i*10+j] = value;
}
void modify(int *a)
{
setelement(a, 1, 2, 12);
setelement(a, 2, 5, 25);
}
void main()
{
int *a;
a = (int *) malloc( 5*10*sizeof(int*));
modify(a);
printf("a(1,2)=%d, a(2,5)=%d\n",getelement(a,1,2),getelement(a,2,5));
}
如果用二维数组,以上用指针实现的过程中把维数设成变量就可以了,但是这样初始化时稍微有点儿麻烦
----------------------
这点没怎么看明白,能否请您把这个说详细点?有例子更好了。谢谢!
第一、就是在前面用二维数组实现的例子中,把5和10改成二维数组的行数和列数就可以了,如:
int m, n;
int **a; /* 二维数组的动态实现只能使用int**类型,这样才可以用a[i][j]方式访问数组元素*/
m = 5, n = 10; /* m 行 n 列的数组 */
a = (int **) malloc( m*sizeof(int *)); /* 这里分配的只是一个指向每一行的指针 */
for(int i=0 ; i<m; i++) /* 稍微有点儿麻烦指这两行,因为还需要给每个行指针分配内存 */
a[i]=(int *) malloc(sizeof(int)*n); /* 这里才是给每行分配存储空间,否则值就是随机的 */
这样,只要设置好行数和列数,调用函数modify(int**)就可以方便地使用二维数组了。
动态二维数组必须象这样初始化,不能写成
a = (int **) malloc( m*n*sizeof(int *));
因为这样其实是分配了m*n个元素的一维数组,使用a[i][j]的方式得到的结果是错误的。
第二、原问题中提到的“二维数组在内存中也是按列排列的”是不对的,在C语言中二维数组是按行排列的,而且这一点儿对于动态创建的二维数组是不成立的,动态二维数组本质上是一个指针数组,和直接用int a[5][10]创建的按行排列的数组有本质的区别。
如果在主程序中用int a[行数][列数];的形式创建二维数组,因为元素是按行排列的,在子程序中就可以按一维数组的方式换算二维数组的坐标:a[i][j] 对应于一维的a[i*列数+j],比如:
void modify(int a[], int col) /* col 是数组的列数,必须要知道列数才能转换二维数组 */
{
a[1*col+2] = 12345;
a[2*col+5] = 67890;
}
void main()
{
int a[5][10], i, j, k;
for ( i = 0, k = 1; i < 5; ++i )
for ( j = 0; j < 10; ++j )
a[i][j] = k++;
printf("修改前:a(1,2)=%d, a(2,5)=%d\n",a[1][2],a[2][5]);
modify((int*)a, 10);
printf("修改后:a(1,2)=%d, a(2,5)=%d\n",a[1][2],a[2][5]);
}
第三、如上两种方法使用的二维数组int**和int[行数][列数]定义的方式,在使用时是不一样的。int**方式只能按二维数组使用,不能象以上这样转换为一维数组使用。要想实现与静态定义的数组一样可以转换为一维数组访问的int**形式的二维数组,在初始化阶段就会更加复杂一些。
这里字数不够贴代码了,如果需要这种代码,请继续追问。
int **a; /* 二维数组的动态实现只能使用int**类型,这样才可以用a[i][j]方式访问数组元素*/
--------
这点是不是有误啊?好像用浮点型也行啊。
请给出后面的代码,谢谢!
嗯嗯,当然,用 float **, double **, struct **等等都是可以的,我说的只能用int**是必须使用**,不是说只能用int。
要让**方式定义的动态数组能够象静态数组那样可以用一维数组访问,就要使动态数组拥有象静态数组那样的连续内存区域,这样建立的动态数组即可以用modify1D()按1维数组访问,也可以用modify2D()按2维数组访问,但是由于内部结构不同,静态数组不能用modify2D()按动态数组方式访问,只能按1维形式使用。代码实现如下:
#include
#include
typedef int ELEMENT_TYPE; /* 数组元素类型,可以是任意类型 */
void modify1D(ELEMENT_TYPE a[], int col)
{ /* 按1维形式访问列数为col的二维数组 */
a[1*col+2] = 12345;
a[2*col+5] = 67890;
}
void modify2D(ELEMENT_TYPE **a)
{
a[1][2] = 12345;
a[2][5] = 67890;
}
ELEMENT_TYPE** make2DArray(int m, int n)
{ /* 建立二维数组 */
ELEMENT_TYPE **a, *b;
int i;
a = (int **)malloc(m * sizeof(int*));
b = (int *)malloc(m * n * sizeof(int));
for ( i = 0; i < m; ++i)
a[i] = b + i * n;
return a;
}
void free2DArray(ELEMENT_TYPE **a)
{ /* 释放二维数组占用的内存,与建立二维数组的过程对应 */
free(&a[0][0]);
free(a);
}
void main()
{
ELEMENT_TYPE ** a;
ELEMENT_TYPE b[5][10];
a = make2DArray(5, 10); /* 建立具有连续内存区域的二维动态数组 */
a[1][2] = 12, a[2][5] = 25;
printf("修改前:a(1,2)=%d, a(2,5)=%d\n",a[1][2],a[2][5]);
modify1D(&a[0][0], 10); /* 这里不能用(int*)a或a[0]调用,必须用&a[0][0] */
printf("修改后:a(1,2)=%d, a(2,5)=%d\n",a[1][2],a[2][5]);
a[1][2] = 12, a[2][5] = 25;
printf("修改前:a(1,2)=%d, a(2,5)=%d\n",a[1][2],a[2][5]);
modify2D(a);
printf("修改后:a(1,2)=%d, a(2,5)=%d\n",a[1][2],a[2][5]);
free2DArray(a);
b[1][2] = 12, b[2][5] = 25;
printf("修改前:b(1,2)=%d, b(2,5)=%d\n",b[1][2],b[2][5]);
modify1D((int*)b, 10); /* 这里可以用 (int*)b 或 b[0] 或 &b[0][0] 三种方式 */
printf("修改后:b(1,2)=%d, b(2,5)=%d\n",b[1][2],b[2][5]);
}
...二维数组已经在主函数中用动态数组分配了空间。
如果在子函数的形参中固定了最后一个维度的话,就没有任何灵活性了。我给子函数传了数组的首地址,然后在子函数中用一维数组的形式赋值(我主要是想赋值),但是在主函数中调用数组时值不对,也就是说值并没有被修改,不是说二维数组在内存中也是按列排列的么?难道在子函数中这个列就不管用了? 追答 如果用二维数组...
C语言 主函数中输入数组 怎样在子函数中调
把数组名作为实参,传递给子函数即可,这是地址传递,子函数中处理的结果将影响到主函数数组的元素值。课本上“数组做函数参数”部分应该有例子可以参考。
关于C语言的二维数组作为函数参数的问题?
int (*arr)[m];所以,传递二维数组作为参数,实际上就是传递了一个指针。将形参的类型定义成int*,再在函数内部转换回指向数组的指针就行了,比如:void f(int *p,int row,int column){ int (*arr)[column]=(int (*)[column])p;\/\/使用二维数组arr } 这样传递参数:int n=5,m=6;int a...
C语言,如何在子函数中写一个3*3二维数组,给主函数调用!!
在子函数申请二维数组,主函数使用,可以用动态申请。方法不止一种,我这里用指针的指针实现二维数组。二维数组除了行列,本身地址也是连续的,从第一行第一列的元素地址++,可以取出所有元素。所以我这里先申请了完整的连续地址。include<stdio.h>#include<malloc.h>int ** sr(void){ int i,j; ...
C语言,如何在子函数中写一个3*3二维数组,给主函数调用!!
在子函数申请二维数组,主函数使用,可以用动态申请。方法不止一种,我这里用指针的指针实现二维数组。二维数组除了行列,本身地址也是连续的,从第一行第一列的元素地址++,可以取出所有元素。所以我这里先申请了完整的连续地址。include<stdio.h>#include<malloc.h>int ** sr(void){ int i,j; ...
c语言中怎么用二维数组作为函数参数
二维数组作为函数参数,实参可以直接使用二维数组名,在被调用函数中对形参数组定义可以指定所有维数的大小,也可以省略第一维的大小说明,如:它们是合法且等价,也可以使用如下形式:但不能省略第二维的大小,如下面的定义是不合法的,编译时会出错:因为从实参传递来的是数组的起始地址,如果在形参中不...
c语言中在不知道二维数组行列数的情况下怎么在函数里调用这个二维数组...
行数 = sizeof(array)\/sizeof(array[0]);列数 = sizeof(array[0])\/sizeof(array[0][0]);你也可以在函数形参里加入行列值,然后主函数调用子函数的时候,把行列数做为参数传过去。
C语言中如何将二维数组作为函数的参数传递?
函数原型 type fun (type (name*)[size])\\x0d\\x0a \\x0d\\x0atype是你要定义的类型,fun是函数名,name是在函数中二维数组的名字,\\x0d\\x0asize是二维数组第2维的长度。\\x0d\\x0a这样调用这个函数只需要把二维数组函数名传递就可以了。
c语言中如何在子函数中调用主体函数的结构数组
有两种方式:1.将结构体声明为全局变量 2.将改结构体作为参数传给子函数,这样子函数就可以使用该结构体了
如何通过函数调用二维数组
C语言编程的过程中,不可避免的会碰到二维或二维以上的数组作为函数的形参的情况,在以前的编程过程中,习惯了动态数组的应用,很是使用直接定义高维数组。最近在编程的过程中就碰到了这个问题:有如下的测试程序:voidtest(double **x,int Row,int Col);voidtest(double **x){ for(int i=0...