【问题标题】:In C,why is definition of a global variable in a separate statement raising warning,but is OK for a local variable?在C中,为什么在单独的语句中定义全局变量会引发警告,但对于局部变量可以?
【发布时间】:2013-03-31 21:45:25
【问题描述】:

在下面的代码中,为什么全局变量“x”的定义显示警告“数据定义没有类型或存储类”但同样的事情对局部变量“y”工作正常?我正在做的一切对于每个变量,首先在一个语句中声明它们,然后在另一个语句中定义它们。它对一个变量工作正常但对另一个变量显示警告有什么区别?

    #include<stdio.h>

      int x;
      x=303;

     int main(void)
      {
        int y;
        y=776 ;

        printf("The value of x is %d,and of y is %d",x,y);
      }

【问题讨论】:

  • 该代码甚至无法编译。您不能在全局范围内拥有语句。
  • 恐怕它在 CodeBlocks (Windows) 中编译得很好,并根据需要显示输出。但是编译会抛出我提到的警告。你使用的是哪个编译器?
  • “首先在一个语句中声明它们,然后在另一个语句中定义它们” - 不,您在一个语句中定义(并声明)它们并在另一个语句中分配给它们。所以你的基础知识错了……是时候更多地学习这门语言了。
  • "那段代码甚至无法编译。" -- 你试过了吗?这是合法的 C89。

标签: c expression declaration


【解决方案1】:

您正在 C89 模式下编译。

  int x;

x的暂定定义。

  x=303;

然后被解释为具有隐式类型int (int x = 303;) 的变量x 的定义。在 C99 或更高版本下,由于废除了“隐式 int”规则,并且没有“隐式 int”规则,该代码将无法编译,第二行只能解释为语句,这在文件范围内是不允许的.

使用-std=c89 -Wall -Wextra -pedantic 编译(并将return 0; 添加到main),gcc 警告

redef.c:4:1: warning: data definition has no type or storage class [enabled by default]
redef.c:4:1: warning: type defaults to ‘int’ in declaration of ‘x’ [-Wimplicit-int]

【讨论】:

  • 为什么会警告“无类型或存储类”?这似乎表明添加存储类(仍然不是显式类型)会使警告消失?
  • 我必须承认我不知道细节,C89不是我的强项。它还用extern x = 303; 发出警告(因为初始化extern 没有多大意义),不能用static 编译(因为之前的extern 声明)。如果没有上一行,而使用static x = 303;,它只会给出implicit int 警告。
  • 如果它们都被声明为静态,则它应该编译,否则第一个是暂定的外部定义,第二个是显式的静态定义,所以它会有冲突的声明。
  • @teppic 是的。如果第一个是static int x;,那么后面的static x = 303;就没有问题了。
  • “为什么它会警告“没有类型或存储类”? -- 你在x=303; 中看到了类型或存储类吗?我不。 “这似乎表明添加存储类(仍然不是显式类型)会使警告消失?” ——它实际上并没有表示任何这样的事情。警告说两者都不见了。添加一个可能会导致警告说只有一个丢失。编译器会针对static x = 303; 发出警告吗?可以,但不是必须的。
【解决方案2】:

原因是这两行:

  int x;
  x = 303;

由声明语句 (int x;) 和用作语句的表达式 (x = 303;) 组成。 C 编程语言只允许在全局范围内进行声明和定义,而不允许在全局范围内使用表达式。但是,声明语句和表达式语句在 C 函数内部都是合法的。

一种直观的思考方式如下:代码x = 303;何时会在全局范围内执行?想象一下我们有这个程序:

int x = 1;

void myFunction() {
    printf("%d\n", x);
}

x = 303;

这里,x 会看到 myFunction 的什么值?它会看到值 1,还是会看到值 303?

另一方面,如果我们有

void myFunction() {
    int x;
    x = 303;
    printf("%d\n", x);
}

更清楚一点,我们应该按顺序执行这些语句,所以303 会被打印出来。

希望这会有所帮助!

【讨论】:

    【解决方案3】:

    您不能在任何函数/块之外执行代码。 x=303; 在你写它的位置无效。

    在这种精确的情况下(全局范围),你只能直接用int x=303初始化变量。

    【讨论】:

      猜你喜欢
      • 2023-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多