我试图理解数组声明中指针和数组的混合使用。全局变量声明和define指令的使用使我有些困惑。该代码段如下所示。
#include <stdio.h>
const int ts1[2] = {(1), (2)};
const int ts2[2] = {(2), (3)};
const int ts3[2] = {(3), (4)};
const int ts4[2] = {(4), (5)};
#define tc1 {1,2}
#define tc2 {2,3}
#define tc3 {3,4}
#define tc4 {4,5}
int main()
{
const int arr1[][2][2] = {{{(1), (2)}, {(2), (3)}}, {{(3), (4)}, {(4), (5)}}};
const int *arr2[2][2] = {{ts1, ts2}, {ts3, ts4}};
const int arr3[][2][2] = {{tc1, tc2}, {tc3, tc4}};
const int *arr4[2][2] = {{tc1, tc2}, {tc3, tc4}};
printf("%d\n", arr2[1][1][1]);
printf("%d\n", arr3[1][0][1]);
printf("%d\n", arr4[1][0][1]);
return 0;
}
arr1是声明数组的常规方法。 arr2 w /全局var decl和arr3 w / define指令也可以正常工作。但是,带有定义指令的arr4在运行时向我发出段错误。考虑到define指令只是将其定义的内容替换为arr4的初始化列表,为什么arr2可以工作而arr4不能工作?
答案 0 :(得分:1)
应用宏替换时,此操作:
const int *arr4[2][2] = {{tc1, tc2}, {tc3, tc4}};
成为:
const int *arr4[2][2] = {{{1,2}, {2,3}}, {{3,4}, {4,5}}};
arr4
是int *
的2D数组,但是您为每个{1,2}
元素分配了int *
之类的内容。如果您使用复合文字,这可以起作用:
const int *arr4[2][2] = {{(int [])tc1, (int [])tc2}, {(int [])tc3, (int [])tc4}};
哪个会成为:
const int *arr4[2][2] = {{(int []){1,2}, (int []){2,3}}, {(int []){3,4}, (int []){4,5}}};
然后,您将一个实际数组分配给arr4
的每个元素,该数组会变为指向其第一个元素的指针。
这有效:
const int *arr2[2][2] = {{ts1, ts2}, {ts3, ts4}};
因为ts1
,ts2
,ts3
和ts4
是类型int
的数组,所以在这里使用它们会导致它们衰减为指向他们的第一个元素。