c语言 传递二维数组警告指针不匹配

定义的函数

int** aFunc(int** a) {
    int **b = **a; 
    retrun b
}

int main() {
    int a[2][2]={{1,1},{2,2}}
    int **b = aFunc(a);// 这里会出现警告
}

出现警告

incompatible pointer types passing 'int [n][n]' to parameter of type 'int **' [-Wincompatible-pointer-types]
int **int[][]不一样,那这里应该怎么写才可以消除这个警告。

为什么会出现这个警告?因为二维数组是知道每行元素占多少地址?
谢谢大神指点!

阅读 6.7k
2 个回答

你说的对,其实就是因为二维数组知道每行元素占多少地址。。。。在aFunc里面是不能写成a[1][1]的(不是真的不可以写),所以给出的只是警告,一般情况下不会出什么问题。

typedef int (* pt1)[2];
typedef int **pt2;
pt1 p1 = NULL;
pt2 p2 = NULL;

pt1pt2是两种不同的类型。
无论如何(32位程序)一个指针占用四个字节。定义指针的类型的意义除了在编译的时候检查类型,还有就是让指针的加/减法有意义(或者说更加方便)。p1++ 的意思是指向下一个元素,而当前这个元素占用多大的内存就记录在指针的类型中了。

为了统一/减少概念性的东西,二维数组被认为是一个一维数组其中的每一个元素又是一个一维数组。所以指针++指向下一个元素,编译器就必须知道数组的第一维有多大,这个第一维有多大就记录在指针的类型里面。 所以其实pt1的意思是,这是一个指针,它指向的元素占用2个int型的空间。pt2的意思是,这是一个指针,它指向的元素占用了4个字节(32位程序,或者说它指向的元素是一个指针)。

因为编译器从来不检测数组越界,所以指针的最后一维的值是不需要记录在指针类型中的。

int p1[7],p2[3];
int pp1[2][4];
int pp2[4][4];

因为编译器从来不检测p1[10]是否是合法,所以p1的类型里面不需要包含7这个信息,因此p1p2是相同的类型,同样pp1pp2也是相同的类型。

所以编译器出现警告就是因为两者的类型不同,所以消除警告的方式就是强制类型转换或者是把函数的形参和实参写为相同的类型,比如int ** aFunc(int a[][2])

int main() {
    int* pa[2] 
    int a[2][2]={{1,1},{2,2}}
    pa[0] = &a[0][0];
    pa[1] = a[1];
    int **b = aFunc(pa);// 这里会出现警告
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进