不在函数内部时导致语法错误的结构成员赋值
我想用C编程语言为(用户定义的)全局变量赋一个特定的值。 当我在任何其他function或主要内容中执行此操作时,它很好。 但是当我从全局空间(在任何函数之外)执行此操作时,它会给出以下编译错误:
[expected '=', ',', ';', 'asm' or '__attribute__' before '.' token]
以下是导致问题的代码段:
#include #define MAX_SIZE 5 typedef struct { int val[MAX_SIZE]; int top; }stack_t; stack_t s; s.top = -1; // <== Initialization from here is causing compilation error main() { //s.top = -1; < === Initialization from here is fine printf("s.top =%d\n", s.top); return 0; }
但是整数变量的相同类型的赋值不仅仅是警告
#include int i,j,k,l; k=10; main() { printf("i= %d, j=%dk=%dl=%d\n", i, j, k, l); return 0; }
任何人都可以告诉原因吗?
分配s.top
的错误并不令人惊讶。 它不是初始化而是分配,而且这些是C中的不同概念。您不能在函数之外进行赋值。
这里有趣的部分是看起来你可以做整数变量k的赋值。 但这是一种幻觉,因为在这种情况下,它不是一个任务,而是一个初始化!
这条线
k = 10;
被解释为不是赋值而是变量定义。 提示这一点是GCC发出警告“数据定义没有类型或存储类”和“在’k’的声明中默认为’int’”。 所以该行可以写成
int k = 10;
正如Matt在下面的评论中写道的那样,忽略这样的数据类型似乎是GCC扩展,而不是标准允许的内容。
(顺便说一句,在编译器中打开警告,并注意它们!)
但是等等,上面那行已经没有k的定义了,你不能有多个定义,是吗?
首先,请记住C对定义和声明进行了区分。 变量的定义是在“创建”变量时,并可选择为其赋予初始值。 声明就是当你告诉编译器变量存在时,它的名称和数据类型,但定义在别处。 您可以同时拥有同一变量的定义和一个或多个声明。 例如:
int xxx = 10; // This is the definition of xxx int xxx; // This is a declaration of xxx int xxx; // Another delaration of xxx
但有时编译器无法确定它看到的是声明还是定义,然后将其解释为“暂定”,或者换句话说“可能是一个定义,也许只是一个声明,我们稍后会决定”。 例如:
int yyy;
这是变量yyy的定义(没有初始值),还是只是一个声明,定义将在别处找到? 编译器不知道,因此等待决定,并将其称为暂定定义。
当编译器看到你的第一个k声明(以及其他变量i,j和l)时,它被解释为一个暂定的定义,当找到后面的定义时,k的暂定定义将被确定为声明,不是定义。
C代码必须在函数内部。 您可以在函数外部声明全局,但不能在函数外部编写赋值语句。 也就是说,您可以将初始值设置为声明结构的一部分,但您无法更改它。 这里你的声明只是“stack_t s;” 线。
C中的所有内容最终都以二进制格式编译为符号(例如ELF格式)。 符号具有名称,因此函数被命名为代码块,而全局变量被命名为数据块。 编译后的二进制文件中没有“自由浮动”块,一切都必须在名称下。
在C模型中,浮动在函数外部的代码没有意义,因为C没有运行该代码的位置。 C永远不会以bash或Python或javascript的方式运行文件; 它只运行二进制文件。 所以它只运行命名函数。 这些文件仅在编译时而不是运行时已知。
初始化main
外部是该错误的原因。 你可以这样使用。
stack_t s={.top=-1};
它将允许您在声明时进行初始化。 请参阅此链接。 或者这很有用。
赋值和初始化之间存在差异 。 您应该注意,分配不能在函数之外完成。 该声明
s.top = -1;
是一个赋值而不是初始化 。
C99和后者提供了结构和数组的指定初始化 。 因此,您只能将struct s
top
成员初始化为
stack_t s = { .top = -1 };
其他成员将由编译器初始化为0
。
在全局空间中,您只能初始化和声明变量,但不能将值赋给变量。 在您的代码中,您将值分配给struct的成员,因此它的抛出错误对于下面的代码的整数也是如此。
在全局空间中尝试以下代码,它工作正常:
typedef struct { int val[MAX_SIZE]; int top; }stack_t; stack_t s={{},-1}; main() { printf("s.top=%d",s.top); return 0; }