栈,和堆的二维数组是不一样的。

比如int a[n][m] 的一个变量,传入一个函数void func(int **a)就会有编译告警,原因为:栈上分配的二维数组数组名int array[n][m]的真实类型是int [ ][ ],在作为右值时才被转化为(int *array)[N] ,和int **是不同的。把前者进行强制转换为后者,在函数中对元素操作也会导致段错误

warning: incompatible pointer types passing 'int [n][m]' to

      parameter of type 'int **' [-Wincompatible-pointer-types]

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
int func(int *array, int m, int n) {
    int i,j;
    for(i=0;i<m;i++) {
        for(j=0;j<n;j++)
            printf("\t%d", *(array +i*n +j));
        printf("\n");
    }
    return 0;
}

int main(int argc,char** argv) {
    int m=3,n=3,i;
    int array[][3] = {{1,2,3},{4,5,6},{7,8,9}};
    func(*array,m,n);
    return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
int func(int *array, int m, int n) {
    int i,j;
    for(i=0;i<m;i++) {
        for(j=0;j<n;j++)
            printf("\t%d",*(array+i*n+j));
        printf("\n");
    }
    return 0;
}

int main(int argc,char** argv) {
    int m,n,i;
    int *array;
    assert(argc == 3);
    m = atoi(argv[1]);
    n = atoi(argv[2]);
    array = (int*)malloc(m*n*sizeof(int));
    for(i=0;i<m*n;i++)
        array[i] = i;
    func(array,m,n);
    return 0;
}

上面两个情况都可以使用这种形式,不过注意第一种入参是数组首元素的地址。