二维数组使用比较少,平时也没有太注意其地址作为指针传递的问题。
描述下遇到的问题:如下所示,本意是想将二维数组首地址作为函数的形参,然后在函数中做一些处理。然后发现直接将首地址传入到test()函数后赋值,程序直接崩溃了。
#include <stdio.h>
int test(long **data)
{
data[0][0] = 1;
return 0;
}
int main()
{
long test_data[4][6];
long *ptr = (long *)&test_data[0];
printf("%p, %p, %p, %p, %p, %p\n", ptr, &ptr, test_data, &test_data[0], &test_data, &test_data[0][0]);
test(test_data);
return 0;
}
查阅了网上的一些资料,大致的意思是二维数组的首地址不能作为二级指针的新参,因为类型不一样。
编译器在解析的时候到底做了什么转换,原因不明。
可以成功的做法:
- 使用一个指针指向二维数组的首地址,然后将指针的地址传给函数
#include <stdio.h>
int test(long **data)
{
data[0][0] = 1;
return 0;
}
int main()
{
long test_data[4][6];
long *ptr = (long *)&test_data[0];
printf("%p, %p, %p, %p, %p, %p\n", ptr, &ptr, test_data, &test_data[0], &test_data, &test_data[0][0]);
test(&ptr); //传递指针地址
return 0;
}
- 修改形参的格式,将long **data 改成 long (*p)[n]的格式,原理应该是将二维数组的首址强制成指向元素的指针传给形参。
#include <stdio.h>
int test(long (*data)[6])
{
data[0][0] = 1;
return 0;
}
int main()
{
long test_data[4][6];
long *ptr = (long *)&test_data[0];
printf("%p, %p, %p, %p, %p, %p\n", ptr, &ptr, test_data, &test_data[0], &test_data, &test_data[0][0]);
test(test_data);
return 0;
}