代码之家  ›  专栏  ›  技术社区  ›  marshallpenguin

不带大小声明的顶级指针的C数组

  •  2
  • marshallpenguin  · 技术社区  · 14 年前

    这段代码编译并产生我所期望的输出。

    #include <stdio.h>
    
    int* ar[];
    
    int main(void) {    
        ar[0] = 97;
        ar[1] = 98;
        ar[2] = 99;
    
        printf("%i\n", ar[0]);
        printf("%i\n", ar[1]);
        printf("%i\n", ar[2]);
        printf("%i\n", ar[3]);
    
        return 0;
    }
    
    /* output
    97
    98
    99
    0
    */
    

    我有一种感觉,我在这么多层面上做错了。这里有什么不好的影响吗?

    此外,为什么指针数组用作全局变量,而如果我在 main ,gcc引发错误?

    4 回复  |  直到 11 年前
        1
  •  4
  •   Michael Burr    14 年前

    至少有几个问题:

    (一) ar 是一个指针数组-您将向它分配int(并将元素打印为int)。GCC和MSVC都警告过我。

    2) 宣言 应收账 是一个“不完整类型”,因为它没有指定大小。MSVC拒绝链接说它无法解决 应收账 符号,这是我所期望的。GCC会链接,并提供警告:

    warning: array 'ar' assumed to have one element
    

    在这种情况下,我更喜欢MSVC的行为。

    在GCC的情况下,您访问的是3个或4个数组元素的数据,实际上只有1个元素存在,因此,您访问的内存不属于对象,这是未定义的行为。它将导致内存损坏、崩溃或明显工作-即使程序不正确(如在测试中)。

        2
  •  2
  •   nmichaels    14 年前

    两个字:未定义的行为。如果它在主目录中,gcc可以判断 ar 由于其作用域仅限于堆栈,因此未给任何空间。什么时候? 应收账 是全局的,编译器无法确保没有人为其分配空间。可能会对某些系统产生不良影响,而对其他系统则可能运行良好。关键是它不会总是做你期望的事情,因为它做的事情是不确定的。

        3
  •  0
  •   Sridhar Iyer    14 年前

    int*a[]是指针数组。它是一个空数组,您没有给它分配任何空间。代码的行为未定义。。gcc引发/不引发错误是您最不担心的。

        4
  •  0
  •   Henno Brandsma    14 年前

    如果你申报

    int ar[4]
    

    你会没事的。在这种情况下,ar是全局的,初始化为 4个零。然后在main中设置值将覆盖0。

    但是没有维度,就不去。