#include <stdio.h> #include <malloc.h> void** malloc2d(int w, int h, int size) //动态申请二维数组方法 { int j; int rowSize = w * size; int indexSize = h * sizeof(void *); void **a = (void **) malloc(indexSize + h * rowSize); char *dataStart = (char *) a + indexSize; for(j = 0; j < h; j++) a[j] = dataStart + j * rowSize; return a; } int main() { int w,h; scanf("%d %d",&w,&h); //输入动态申请的数组的宽和高 int **m = (int **) malloc2d(w, h, sizeof(int)); //根据输入的宽和高动态申请二维数组 for (int i = 0; i < h;i++) for (int j = 0;j < w;j++) m[i][j] = j + i; for (int i = 0; i < h;i++) { for (int j = 0;j < w;j++) printf ("%d ",m[i][j]); printf ("/n"); } return 0; } /* 参数w,h是所申请二维数组的列数和行数,size是数组单元的字节数。比如,申请一个4*5的int型的二维数组,使用: int **m = (int **) malloc2d(5, 5, sizeof(int)); 直接使用m[x][y]即可以引用x行y列的值。 退回时,直接使用free(m)即可。 跟白老鼠开始的程序相比,改了一些地方,返值改成void **,(char *)(a + h)改成了(char *) a + h。加进了一些循环外的计算。 解释一下~就好像原帖里面cromayen2000所讲的,动态申请二维数组通常需要一个index区域和一个数据区域。index区域保存每一行数据区域的首地址,数据区域存放实际的值。m的地址是index区域的首地址。 这样,对二维数组中x行y列元素的引用m[x][y],实际上是一个两步的运算。 首先,m是一个int**的元素。m[x]是*(m + x),即index区域,第x个元素内的值,这个值就是数据区域第x行的起始地址。*(m + x)的类型是int*。 之后,寻找第y列的值。就是*(*(m + x) + y)。正好对int**进行两次解除引用。得到一个int。而写成中括号的表示法,m[x][y] === *(*(m + x) + y)。 */