为什么这个赋值在函数之外不起作用?
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 在任何函数的范围之外,并且在初始化的范围之外。
这在函数外是不可能的。
代码仅在被调用的函数中执行,初始化除外,初始化发生在初始赋值期间。
这是我正在进行的示例。这第一段代码将不起作用。
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 在任何函数的范围之外,并且在初始化的范围之外。
这在函数外是不可能的。
代码仅在被调用的函数中执行,初始化除外,初始化发生在初始赋值期间。