为什么这个赋值在函数之外不起作用?

Why doesn't this assignment work outside of a function?

这是我正在进行的示例。这第一段代码将不起作用。

typedef struct {
    char *desc;
    unsigned quantity;
} item;

item *inventory[INVENTORY_SIZE];

item thing = { "This is a thing.", 2 };
inventory[0] = &thing;  // Fail.

int main(void){
    // Code goes here.
}

但是,以下代码将起作用。

typedef struct {
    char *desc;
    unsigned quantity;
} item;

item *inventory[INVENTORY_SIZE];

item thing = { "This is a thing.", 2 };

int main(void){
    inventory[0] = &thing;  // Works.
}

我知道我不能在函数外调用函数,但我可以在函数外分配全局变量。这看起来像一个任务。那么为什么它不起作用?

编辑:我一点击'post',我想我就明白了答案。您可以在函数外部的声明中赋值,但前提是它是一个声明。这就是答案,不是吗?

item thing = { "This is a thing.", 2 };

不是作业,尽管它看起来像。它实际上是一个 initialisation(声明的一部分),在函数之外完全有效。

另一方面,

inventory[0] = &thing;

一个赋值,必须在某个描述的函数中。

最重要的是,您不应将初始化规则应用于赋值。

首先,

item thing = { "This is a thing.", 2 }

是一个initialization,这是一个特例,不是赋值。这设置了变量的初始值。初始化与声明绑定,因此它可以驻留在文件范围内。

assignment expression 只能驻留在函数内部。简单来说,一个赋值需要在运行时间执行,所以如果它不在函数范围内,就无法知道什么时候到执行它。

你猜对了:第二个例子是初始化,而不是语句的执行。这是合法的,因为全局变量是在程序执行之前创建的(即,对 main 函数的初始调用)。可以这样想:命令流从 main 函数开始,然后进入从它调用的所有函数,因为它们在程序代码中被调用。因此,程序在任何时候都在某个函数内,并且任何不在某个函数内的命令(除了预先完成的初始化之外)都会自动成为死代码 --- 程序无法访问它们。

这应该有效,如果它是您想要完成的:

item thing = { "This is a thing.", 2 };
item *inventory[INVENTORY_SIZE] = {&thing};

这些是 definitions(因为它们处于顶级范围),因此编译器将继续并在此翻译单元中为它们分配存储空间。

当我们写:

data_type variableName = someValue;

表示我们首先声明variableName为一个变量,类型为data_type。随后,立即完成一个值的分配,因为这是分配给 variableName 的第一个值,它还将它初始化为 someValue .

这是允许的。这是一种特殊类型的函数,一种系统函数,称为初始化。

但是写作

variableName = someValue;

意味着我们试图将 someValue 分配给 variableName 在任何函数的范围之外,并且在初始化的范围之外。

这在函数外是不可能的。

代码仅在被调用的函数中执行,初始化除外,初始化发生在初始赋值期间。