二维数组有两种形式:
①在栈上:
int a[4][4] = {...};
②在堆堆上:
int ** a = new int *[4];
for(int i = 0; i < 4; i++)
a[i] = new int[4];
这两种情况下,二维数组做形参的传参方式是不一样的。
①在栈上时
void fun(int * a, int rownum, int colmunnum) //形参传递按照一维指针
{
...
a[r * colmunnum + c] = ...; //根据行列计算找到对应位置
}
}
void main()
{
int a[4][4] = {...};
fun((int *)a, 4, 4); //调用时强制转换为一维指针
}
}
②在堆上时
void fun(int ** a, int rownum, int colmunnum) //形参传递按照二维指针
{
...
a[r][c] = ...; //直接读取对应位置
}
}
void main()
{
int ** a = new int *[4];
for(int i = 0; i < 4; i++)
a[i] = new int[4];
fun(a, 4, 4); //直接调用
}
}
这两种方式,相互不能串用,会出错。具体原因是因为:
①栈上分配的二维数组,实际类似于一个一维数组,所有的值都连续存储。即使int a[4][4]这样写,a也是一个int (*)[4]型的指针,不是int **,即内容连续存储每4个换一行;
②而堆上分配的 int ** a = new int *[4], 其四个子指针有是分别分配的,内容不连续。故不可以通过r*colnum +c来定位。
如果堆上的二维数组用第一种方式传参,输出会是乱码,因为读取了错误的地址。
而栈上的二维数组用第二种方式传参会报错,读取了没有分配的内存空间。
自己总结的:http://www.cnblogs.com/dplearning/p/4631541.html