简体   繁体   English

为什么不能在 c 中初始化 main() 之外的结构值?

[英]why can't you initialize values of structs outside of main() in c?

I get an error in visual studio with the code:我在 Visual Studio 中收到错误代码:

struct coordinates {
    int x;
    int y;
};
struct coordinates point;
point.x = 5;
point.y = 3;

int main() {
    return 0;
}

it works if I initialize point.x and point.y in main() and / or if I give the point values like this: struct coordinates point = {5, 3} .如果我在main()中初始化point.xpoint.y和/或如果我给出这样的点值,它会起作用: struct coordinates point = {5, 3} Why can't you initialize point.x and point.y outside of main() ?为什么不能在main()之外初始化point.xpoint.y

The form you've written is not initialization ;你写的表格不是初始化 it's an uninitialized (or rather default-initialized, to zero) declaration and definition followed by assignment statements outside of a scope where they're valid.它是一个未初始化(或者更确切地说是默认初始化为零)的声明和定义,后跟有效的 scope 之外的赋值语句。

If you want to initialize the members by name, write:如果要按名称初始化成员,请编写:

struct coordinates point = {
    .x = 5,
    .y = 3,
};

Other answers are (correctly) explaining that there are ways to initialize structs by named member outside main statically but I want to add, for the OP or for others.其他答案(正确)解释了有一些方法可以通过main外部的命名成员静态初始化结构,但我想为 OP 或其他人添加。

The basic idea here is that C doesn't allow executable statements ("code") outside of functions.这里的基本思想是 C 不允许函数之外的可执行语句(“代码”)。 A new C programmer may be coming from another language where code is sort of frequently executed in a "global scope" and you define functions or set variables here and there as you wish.新的 C 程序员可能来自另一种语言,其中代码在“全局范围”中经常执行,您可以根据需要在这里和那里定义函数或设置变量。 C is way older and much more structured than this. C 比这更老,更结构化。 There are global variables (like your point ), which are things you declare outside of any particular function, but you can't really "do stuff" with those variables in the global space itself, except indicate their initial values (static initialization).有全局变量(如您的point ),它们是您在任何特定 function 之外声明的东西,但您不能真正在全局空间本身中对这些变量“做事”,除非指出它们的初始值(静态初始化)。

C doesn't "run through the file executing everything it finds in order"-- each file gets compiled into a unit of object code which then gets linked together with other units and main is (essentially) the entry point for execution, which in turn calls other functions, and so on-- when your code is running, its always "inside" of a function somewhere. C 不会“遍历文件,按顺序执行它找到的所有内容”——每个文件都被编译成一个 object 代码单元,然后与其他单元链接在一起, main是(本质上)执行的入口点,在turn 调用其他函数,依此类推——当你的代码运行时,它总是在某个 function 的“内部”。

It is true that ordering of declarations and definitions within a file matter in C, but this is essentially for the convenience of the compiler, not because things are "executed" or "evaluated" in that order at runtime.确实,在 C 中文件中的声明和定义的顺序很重要,但这本质上是为了编译器的方便,而不是因为在运行时按该顺序“执行”或“评估”事物。 (By the time your code is executing, it's been utterly transformed into something else and the order of statements in the original files has essentially disappeared from view.) (当您的代码执行时,它已完全转换为其他内容,原始文件中的语句顺序基本上已从视图中消失。)

So: With all that said.所以:说了这么多。 it is useful and often desirable to have the values of global variables pre-set at program initialization time.在程序初始化时预先设置全局变量的值是有用的,并且通常是可取的。 So static initialization is sort of special in that it sorta looks like an executable statement but isn't, and thus it has traditionally had a goofy syntax.所以 static 初始化有点特殊,因为它看起来像一个可执行语句但不是,因此它传统上具有愚蠢的语法。 We had that sort of strange ordered = {2, 3} syntax, and now there are more accommodations for the named members to help you accomplish this static initialization.我们有那种奇怪的 ordered = {2, 3}语法,现在有更多的命名成员可以帮助您完成这个 static 初始化。 But you should still think of it as static (one-time, fixed) initialization, not as executing an assignment in the global space, because that isn't what you're actually doing.但是您仍然应该将其视为 static(一次性,固定)初始化,而不是在全局空间中执行分配,因为这不是您实际在做的事情。

Why can't you initialize point.x and point.y outside of main()?为什么不能在 main() 之外初始化 point.x 和 point.y?

You can, using static initialization - but you can't call a function or perform impure operations.您可以使用 static 初始化- 但您不能调用 function 或执行不纯操作。 When using static-initialization prior to C99 you need to ensure fields are set in the correct order, while C99 and later allow for designated initializers that allow arbitrary field initialization.在 C99 之前使用静态初始化时,您需要确保以正确的顺序设置字段,而 C99 及更高版本允许指定的初始化程序允许任意字段初始化。

C code outside of a function are not executable instructions - they're static declarations, consequently they don't have a defined evaluation order. function 之外的 C 代码不是可执行指令 - 它们是 static 声明,因此它们没有定义的评估顺序。

As a thought-experiment, consider this:作为一个思想实验,考虑一下:

int x;
int y;

x = 2;
y = 3;
y = x;
x = y;

int main() {
    
    return x; // what is returned?
}

Maybe you learned Javascript but you are a newbie in c/c++.也许您学习了 Javascript 但您是 c/c++ 的新手。 Every c/c++ program starts with the main function, and every executive code must be in a function.每个 c/c++ 程序都以main function 开头,每个执行代码必须在 function 中。

So if you want to initialize the value of a struct, you should do this in main function.所以如果你想初始化一个struct的值,你应该在main function中做这个。

struct coordinates {
    int x;
    int y;
};
struct coordinate point;
int main(){
  point.x = 5;
  point.y = 3;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM