我试图理解在数组声明中指针和数组的混合使用。全局变量声明和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/global var decl和arr3w/define指令也可以正常工作。但是,arr4 w/define指令在运行时向我发出seg故障。考虑到define指令只是将它定义的内容替换到arr4的初始化列表中,为什么arr2可以工作,而arr4不能?

最佳答案

应用宏替换时,这:

const int *arr4[2][2] = {{tc1, tc2}, {tc3, tc4}};

变成:
const int *arr4[2][2] = {{{1,2}, {2,3}}, {{3,4}, {4,5}}};

arr4int *的一个二维数组,但是您可以将类似于{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}};

因为ts1ts2ts3ts4int类型的数组,所以在这里使用它们会导致它们衰减为指向其第一个元素的指针。

09-25 20:23