全局定义和全局变量声明之间的区别

时间:2018-11-28 19:50:25

标签: c

我试图理解数组声明中指针和数组的混合使用。全局变量声明和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不能工作?

1 个答案:

答案 0 :(得分:1)

应用宏替换时,此操作:

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

成为:

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

arr4int *的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}};

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