C 中变量是在哪个阶段声明并分配内存的?

map*_*ple 1 c

我是 C 新手。我无法理解以下代码中的结果。int a[N]我使用 goto 并跳转array 和的声明int x。虽然x没有初始化10,但我仍然可以访问这些变量。

#include <stdlib.h>
#include <stdio.h>
#define N 4

void printArray(int a[], int length) {
    for (int i = 0; i < length; i++) {
        printf("%d, ", a[i]);
    }
    printf("\n");
}


int main(void) {

    goto done;
    
    int a[N];
    int x=10;
    printf("x=%d\n", x);

    done:
    for (int i = 0; i < N; i++) {
        a[i] = i;
    }
    printArray(a, N);
    printf("x=%d\n", x);

    return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)

结果

0, 1, 2, 3
x=0

Run Code Online (Sandbox Code Playgroud)

我的问题:

为什么我可以访问这些声明被跳转的变量?C语言中如何声明变量?变量声明似乎不是逐行运行的。

ric*_*ici 7

除了“可变长度数组(VLA)”之外,还有一个自动变量的“生命周期从进入与其关联的块开始,直到该块的执行以任何方式结束”。(\xc2\xa76.2.4) 初始化(如果有的话)稍后发生,当程序通过声明时。如果程序不依赖于变量的初始化,则跳过声明是合法的。但无论初始化最终是否会发生,该变量从程序进入块的那一刻起就存在,无论完成如何。(从外部跳入块也是合法的,并且也可能阻止初始化。但是一旦进入块,变量就存在。)

\n

如果程序尝试读取未初始化变量的值,它将收到一个不确定的值。(大多数编译器都会尝试检测发生这种情况的可能性,但您需要启用警告才能查看报告。)

\n

将变量的生命周期“提升”到其封闭块的结果是,程序的一部分存在该变量但不可见(因为它的作用域从定义它的地方开始)。变量然后跳回程序的该区域,您将能够通过指针访问变量的值,这表明作用域和生存期是不同的。

\n

如果变量是 VLA,那么它的生命周期从声明开始,编译器将不允许您跳过声明。VLA 无法初始化,因此您必须为要访问的 VLA 中的每个元素分配一个值。并非所有编译器都实现 VLA。您的示例没有显示 VLA,因为N它是一个扩展为整数常量的宏。

\n