符合中小企业对网站设计、功能常规化式的企业展示型网站建设
本套餐主要针对企业品牌型网站、中高端设计、前端互动体验...
商城网站建设因基本功能的需求不同费用上面也有很大的差别...
手机微信网站开发、微信官网、微信商城网站...
C语言编程的过程中,不可避免的会碰到二维或二维以上的数组作为函数的形参的情况,在以前的编程过程中,习惯了动态数组的应用,很是使用直接定义高维数组。最近在编程的过程中就碰到了这个问题:有如下的测试程序:
广灵ssl适用于网站、小程序/APP、API接口等需要进行数据传输应用场景,ssl证书未来市场广阔!成为创新互联的ssl证书销售渠道,可以享受市场价格4-6折优惠!如果有意向欢迎电话联系或者加微信:028-86922220(备注:SSL证书合作)期待与您的合作!
voidtest(double **x,int Row,int Col);
voidtest(double **x)
{
for(int i=0;iRow;i++)
for(int k=0;kCol;k++)
x[i][k] += 100.0;
}
intmain(int argc, char *argv[])
{
/*
double **x;
x = new double *[3];
for(int i=0;i3;i++)
x[i] = new double[3];
*/
double x[3][3];
for(int i=0;i3;i++)
for(int k=0;k3;k++)
x[i][k] = i*k;
test(x,3,3);
for(int i=0;i3;i++)
for(int k=0;k3;k++)
printf("x[%d][%d]= %e\n",i,k,x[i][k]);
getch();
return 0;
}
编译时提示Cannot convert 'double [*][3]' to double **'。
将调用方式强制进行类型转换:test((double **)x),编译通过,运行出错,提示非法越界。
据传:因为栈上分配的数组和堆上分配的数组在内存排列上可能不相同,直接定义的数组是存储在程序的堆栈区,数据占用连续的区间;而动态申请的数组是在系统的远堆上(far heap),除最后一维的元素是连续存放的外,其他维上的元素有可能不是在一块连续的内存区域里。
//栈上:
int ia[2][2] = {2,3,4,5}; //4个元素是连续排列的内存段
//堆上:
int **p = new int*[2]; //只有每行内是连续排列,各行并不一定连续排列
for ( int i = 0; i 2; i++ )
{
p[i] = new int[2];
}
for ( int i = 0; i 2; i++ )
{
for ( int j = 0; j 2; j++ )
{
p[i][j] = ia[i][j];
}
}
所以对栈上的数组用int **p指向首地址,因为int **p一次解引用为地址指针,而非堆上的指向数组的指针,所以二次解引用会出错。
如果找一个通用方程只能用:
void f( int *p, int row, int col ) //给出数组的行和列,对堆上的数组不合适
{
for ( int i = 0; i row; i++)
{
for ( int j = 0; j col; j++ )
{
cout p[i * row + j] " ";
}
cout endl;
}
}
int main(){
//.........
int ia[2][2] = {2,3,4,5};
f( (int*)ia, 2, 2 );
}
采用上面的通用办法还是比较麻烦,这无形中对编程增加了难度,为了避免这个麻烦可以采用动态数组的形式,将原来采用直接定义的数组全部换成动态数组,类似开头例子中被注释掉的那部分代码,当然这样也有后续的麻烦,动态数组的生命周期完成后必须释放内存空间,这也有点罗嗦,但是毕竟可以直接使用数组的形式,比上面的通用方式还是要简单一点。
如果执意要使用直接定义的数组该怎么办呢?有如下几种方法:
方法一:
voidtest(double (*x)[3], int Row, int Col);
调用方式:test(x,Row,Col);
调用用方式 test(x,Row,Col);
方法二:
voidtest(double x[][3], int Row,int Col);
调用方式 test(x,Row,Col);
对于多维数组作为参数,除第一维之外的其它维必须指定维数,否则是肯定编译不过去的。
从上面的对直接定义的数组的引用情况看,直接定义的数组的使用比较麻烦,一旦直接定义数组的维数发生变换,函数的定义必须相应的修改,否则程序就会出错,这也增加了程序进一步开发的麻烦,为了一劳永逸的解决这个问题,建议还是使用动态数组的方法,虽然需要手工释放内存,但是除却了后续的麻烦。
行数 = sizeof(array)/sizeof(array[0]);
列数 = sizeof(array[0])/sizeof(array[0][0]);
你也可以在函数形参里加入行列值,然后主函数调用子函数的时候,把行列数做为参数传过去。
标号j 标号 i 0 1 2
0 1 2 3
1 4 5 6
2 7 8 9
fun()返回值 s=a00+a01+a02+a10+a11+a20
=1+2+3+4+5+7
=22
函数调用不能这么用,第36行。C标准里面返回值是不能直接返回一个数组的,只能返回数组的首地址。输出学生成绩和每科成绩那个函数,你可以定义一个全局变量数组,还有求平均值最好用float 或者double,用int会造成精度流失。帮你调试了一下,大概就这样吧
正如楼下所言
int
**p
,定义的p是一个指向int*型的指针
int
(*p)[10]是一个指向数组的指针
数组长度为10
假如定义成
deal(int
**p),传参数时要加强制类型转换:
deal((int**)a);
并且使用p时不能用下标,p[2][3]是错误的,因为不知道p指向的int*型的长度,无法编译成*(p+2*10+3)
必须自己写成*(p+2*10+3)来调用
假如定义成
deal(int
(*p)[10])就不一样了,编译器就能知道p是一个指向长度为10的数组的指针
那么p[2][3]就能编译成*(p+2*10+3)了
总之,c语言是很灵活的,不同的定义方式配上不同的用法,都是能得到正确的结果的
不知道这么说楼主明白了没?
同样的还有多维数组对多维指针的问题,楼主可以自己类推一下
3种方法
1.将该二维数组设置成public,然后再main里面声明类的对象可以直接调用。
2.将该二维数组设置成static public,然后再main里面用类直接调用。
3.将该二维数组设置成private,然后在类里面声明两个函数,一个get这个数组,一个set这个数组。然后再main函数通过声明类的对象来调用这两个函数来设置和取得这个二维数组。
一般的做法是第三种,保证类数据的私有性。