不在函数内部时导致语法错误的结构成员赋值

时间:2014-12-27 05:01:22

标签: c

我想用C编程语言为(用户定义的)全局变量赋一个特定的值。当我在任何其他功能或主要内容中执行此操作时,它很好。但是当我从全局空间(在任何函数之外)执行它时,它会给出以下编译错误:

[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;
}

但是整数变量的同类赋值不​​仅仅是警告

#include <stdio.h>

int i,j,k,l;
k=10;
main()
{
        printf("i= %d, j=%d k=%d l=%d\n", i, j, k, l);
        return 0;
}

有人可以告诉原因吗?

5 个答案:

答案 0 :(得分:13)

分配s.top时的错误并不令人惊讶。它不是初始化而是分配,而这些是C中的不同概念。您不能在函数之外进行赋值。

这里有趣的部分是看起来你可以分配整数变量k。但这是一种幻觉,因为在这种情况下,它不是一个任务,而是一个初始化!

该行

k = 10;

不是解释为赋值,而是解释为变量定义。对此的暗示是GCC发出警告&#34;数据定义没有类型或存储类&#34;和&#34;类型默认为&#39; int&#39;在宣布&#39;&#39;&#34;。所以该行可以写成

int k = 10;

正如Matt在下面的评论中写道的那样,忽略这样的数据类型似乎是GCC扩展,而不是标准允许的内容。

(顺便说一句,执行打开编译器中的警告,并注意它们!)

但是等等,上面的行上已经没有k的定义了,你可以拥有多个定义,不是吗?

首先,请记住C对定义和声明进行了区分。变量的定义是当你&#34;创建&#34;变量,并可选择为其提供初始值。声明就是当你告诉编译器变量存在时,它的名称和数据类型,但定义在别处。您可以同时拥有同一变量的定义和一个或多个声明。例如:

int xxx = 10; // This is the definition of xxx
int xxx; // This is a declaration of xxx
int xxx; // Another delaration of xxx

但有时编译器无法确定它所看到的是声明还是定义,然后将其解释为&#34;暂定定义&#34;,或者换句话说&#34;或许一个定义,也许只是一个声明,我们稍后会决定&#34;。例如:

int yyy;

这是变量yyy的定义(没有初始值),还是只是一个声明,定义会在其他地方找到?编译器不知道,所以等待决定,并将其称为暂定定义。

当编译器看到你的第一个k声明(连同其他变量i,j和l)时,它被解释为暂定定义,当找到后面的定义时,k的暂定定义将被确定为宣言,而不是定义。

答案 1 :(得分:8)

C代码必须在函数内部。您可以在函数外部声明全局,但不能在函数外部编写赋值语句。也就是说,您可以将初始值设置为声明结构的一部分,但您无法更改它。这里你的声明只是“stack_t s;”线。

C中的所有内容最终都以二进制格式编译为符号(例如ELF格式)。符号具有名称,因此函数被命名为代码块,而全局变量被命名为数据块。在编译的二进制文件中没有“自由浮动”的块,所有内容都必须在名称之下。

在C模型中,浮动在函数外部的代码没有意义,因为C没有运行该代码的位置。 C永远不会以bash或Python或javascript的方式运行文件;它只运行二进制文件。所以它只运行命名 功能。这些文件只在编译时而不是运行时才知道。

答案 2 :(得分:7)

初始化main外部是导致该错误的原因。你可以这样做。

stack_t s={.top=-1};

它将允许您在声明时进行初始化。请参阅此link.this这可能很有用。

答案 3 :(得分:1)

differences between assignment and initialization。您应该注意,分配不能在函数之外完成。声明

s.top = -1;  

是一个赋值而不是初始化

C99和后者提供designated initialization结构和数组。因此,您只能将struct top的{​​{1}}成员初始化为

s

和其他成员将由编译器初始化为stack_t s = { .top = -1 };

答案 4 :(得分: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;
}