C 结构成员赋值不在函数内时导致语法错误
我想在C编程语言中为(用户定义的)全局变量指定一个特定值。当我在任何其他函数或主函数中执行此操作时,它是好的。但是,当我从全局空间(在任何函数之外)执行此操作时,会出现以下编译错误:C 结构成员赋值不在函数内时导致语法错误,c,C,我想在C编程语言中为(用户定义的)全局变量指定一个特定值。当我在任何其他函数或主函数中执行此操作时,它是好的。但是,当我从全局空间(在任何函数之外)执行此操作时,会出现以下编译错误: [expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘.’ token] 以下是导致问题的代码段: #include <stdio.h> #define MAX_SIZE 5 typedef struct { int val[MA
[expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘.’ token]
以下是导致问题的代码段:
#include <stdio.h>
#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;
}
#包括
#定义最大尺寸5
类型定义结构
{
int val[最大值];
int top;
}堆叠;
堆栈;
s、 top=-1;// 在main
外部初始化是该错误的原因。你可以像这样使用它
stack_t s={.top=-1};
它将允许您在声明时进行初始化。请参考此内容,否则可能会很有用 C代码必须位于函数内部。可以在函数外部声明全局,但不能在函数外部编写赋值语句。也就是说,您可以将初始值设置为声明结构的一部分,但随后不能更改它。这里您的声明只是“堆栈”行
C中的所有内容最终都编译成二进制格式的符号(例如ELF格式)。符号有名称,因此函数被命名为代码块,全局函数被命名为数据块。编译后的二进制文件中没有“自由浮动”块,所有内容都必须使用一个名称
在C模型中,在函数外部浮动的代码没有意义,因为C没有运行该代码的位置。C永远不会像bash、Python或javascript那样运行文件;它只运行二进制文件。所以它只运行名为
功能。只有在编译时而不是运行时才知道这些文件。在全局空间中,您只能初始化和声明变量,但不能将值分配给变量。在您的代码中,您正在将值分配给struct的成员,因此它的抛出错误对于下面代码中的整数也是如此
在全局空间中尝试以下代码,效果良好:
typedef struct
{
int val[MAX_SIZE];
int top;
}stack_t;
stack_t s={{},-1};
main()
{
printf("s.top=%d",s.top);
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;
但有时编译器无法确定它看到的是一个声明还是一个定义,然后将其解释为“暂定定义”,或者换句话说,“可能是一个定义,可能只是一个声明,我们稍后再决定”。例如:
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的暂定定义将被确定为一个声明,而不是定义。有。您应该注意,赋值不能在函数之外完成。声明
s.top = -1;
是一个赋值而不是一个初始化
C99和后者提供了一系列结构和数组。因此,您只能将structs
的top
成员初始化为
stack_t s = { .top = -1 };
其他成员将由编译器初始化为0
。:感谢您的回复,我知道我们可以在声明为可能时初始化。但对于整数变量,编译器不会抛出error@sudhi一个正态变量,你可以这样做inta;a=10
它将发出警告数据定义没有类型或存储类[默认情况下启用]
。我也很好奇为什么在main()之外初始化会导致编译错误。{}
在CI中不是有效的初始值设定项,请相信它的{0}
。但是使用{}
编译器并没有抛出错误。让我知道你的评论-@Matt McNabbYou依赖于编译器扩展,如果{}
没有给出错误这些行:stack\t s;s、 top=-1;不是初始化。初始化将是:stack_t s={“”-1};实际的可执行代码,例如第二行(s.top=-1;)是可执行赋值,而不是初始化代码>定义为GCC扩展;标准C中不允许这样做。请参见6.7.2/2“每个声明中的声明说明符中至少应给出一个类型说明符”。我认为这在C89中是合法的,在C99和C11中肯定不合法however@ThomasPadron-麦卡锡:谢谢你清晰的解释