为什么不能全局定义结构成员?

时间:2019-06-16 10:24:44

标签: c struct

在全局定义struct时,为什么也不能在全局范围内定义结构成员(除了使用初始化语法之外)?我从c中得到的错误是system_1具有“未知类型名称”。

如果在函数中定义结构,例如main(),则不会遇到任何问题。

typedef struct Light_System {
    int redLightPin;
    int yellowLightPin;
    int blueLightPin;
} Light_System;

Light_System system_1;

# "Light_System system_1 = {4, 0, 0}" works

system_1.redLightPin = 4; # doesn't work

int main(int argc, char *argv[]) {
    # placing everything in here works
    # placing just "system_1.redLightPin = 4;" here makes it work.
    printf("%d\n", system_1.redLightPin);
    return 0;
}

我希望我能够在全局范围内定义结构的成员。

3 个答案:

答案 0 :(得分:5)

  

全局定义结构时,为什么不能全局定义结构成员(除了使用初始化语法以外)?

因为您要执行的操作不是定义初始化。这是任务。您可以在全局范围内声明,定义和初始化,但不能分配。

这不仅适用于结构。它也适用于变量。在函数之外,您只能声明和初始化变量。您不能进行常规作业,也不能做任何其他事情。我不确定100%的细节,但我非常有信心,您无法在全局范围内执行编译期间无法完成的任何事情。

这将起作用:

int x=5;

但不是这样:

int x;
x = 5;

好吧,实际上它是有效的,但是会产生关于warning: data definition has no type or storage classwarning: type defaults to ‘int’ in declaration of ‘x’的神秘警告。但是,仅仅因为它可以编译,它就不会按照您的想法去做。实际上,您不理解的隐式警告通常可以很好地表明代码将执行您既不希望也不理解的事情。该代码的作用是对x隐式重新声明,然后进行初始化。如果尚未提前初始化,则允许使用,因此无效:

int x = 3;
x = 5; // Not ok, because x is already initialized

这里的错误消息清楚地说明了为什么上一个示例进行了编译:{{1​​}}。

同样,这也是无效的:

error: redefinition of ‘x’

出现此错误:

int x = foo();  

答案 1 :(得分:2)

正如其他人所说。您不能在全局范围内分配。但是您可以初始化。因此,如果要全局初始化结构成员,可以尝试这样。

#include <stdio.h>

typedef struct Light_System {
    int redLightPin;
    int yellowLightPin;
    int blueLightPin;
} Light_System;
Light_System ls = {10,5,3};

int main()

{
    printf("%d %d %d",ls.redLightPin,ls.yellowLightPin,ls.blueLightPin);
}

应该编译。

因此,如果您想知道为什么会这样,那是因为全局变量在编译时以给定值存储在应用程序的.data节中。但是赋值是只能在功能范围内执行的指令。因此,编译后的内容将保留其时间值。

答案 2 :(得分:0)

您不能在C或C ++函数的外部执行语句。但是您可以在许多编译器(并非全部)中使用C99风格的“指定的初始化程序”:

Light_System system_1 = {
    .redLightPin = 4
};

这将在C ++ 20中成为标准,但是由于相同的语法已经存在于C语言中多年,因此许多编译器也允许在C ++中使用它。

参考:https://en.cppreference.com/w/cpp/language/aggregate_initialization

相关问题