为啥我不能为 C 函数外部的全局变量赋值?

Posted

技术标签:

【中文标题】为啥我不能为 C 函数外部的全局变量赋值?【英文标题】:Why can't I assign values to global variables outside a function in C?为什么我不能为 C 函数外部的全局变量赋值? 【发布时间】:2018-11-12 15:34:09 【问题描述】:

假设我有一个全局变量,我想给它分配另一个变量。我发现您可以为函数内的全局变量分配另一个值:

int i = 8;

int main(void)

  i = 9;     /* Modifies i */
  return 0;

但是,在函数外部分配全局变量不起作用!

int i = 8;

i = 9;  /* Compiler error */

int main(void)

  return 0;

我收到以下错误消息:

warning: data definition has no type or storage class
warning: type defaults to 'int' in declaration of 'i'
  error: redefinition of 'i'
note: previous definition of 'i' was here
int i = 8;
    ^

为什么会这样?

【问题讨论】:

当它在函数之外时,你希望它什么时候执行? 在函数之外只允许定义和声明。你不能有一般性的陈述。这就是指定语言的方式。 这对 SO 来说不是一个好问题。唯一合理的答案是“因为这就是语言的设计方式”这一主题的变体——问为什么这样设计是没有建设性的;自古以来就是这样,在这个问题上不会改变。曾经有一个古老的标准,您可能已经能够在文件范围内写入i = 9;,并且它会隐含类型为int,但GCC 8.1.0 警告data definition has no type or storage class-std=c90,有或没有-pedantic . 您是否考虑过更有效的int i = 9; 而不是int i = 8; i = 9;?代码执行从main()开始。 @DeiDei 实际上这是一个有效的观点。 【参考方案1】:

这是一个全局变量的定义,可选初始化为特定值:

int i = 8;

请注意,执行的不是代码,变量只会被设置为最初包含 8。要么将其视为“魔术”(对于许多未真正由标准定义的事物的有用模型),要么考虑将值复制到内存位置的表任何代码执行之前。

这是一段没有执行它的“框架”的代码。 (或者你打算这样做。编译器有其他意见,见下文。)

i = 9;

没有包含它的函数。目前尚不清楚何时应该执行。这是编译器不喜欢的。 在 C 中,所有代码都必须在函数内部,并且只有在调用该函数时才会执行,例如来自main()

其他语言,主要是那些通过解释它们来执行“脚本”(而不是将代码转换为可执行文件,例如通过编译器)的语言,允许在任何地方拥有代码。 C 不同。

编译器对此有不同的看法:

i = 9;
不在函数内部,所以不能是代码 它看起来像一个变量定义,假设您的意思是它是一个int,即默认值 但依赖默认值不是一个好主意,因此请注意缺少类型并使用默认值 另外,如果它定义,那么它是i的第二个定义,现在这确实是错误的,所以显示错误并编译失败 为了提供帮助,请提及i 的第一个定义在哪里

这就是如何读取您引用的编译器输出。

【讨论】:

不仅“依赖默认值”不好——C89 甚至不支持这种形式,而且 GCC 现在在 gnu11 模式下编译,隐式 int 已经消失了。 @AnttiHaapala 我同意不认为这是一个错误。 OPs 编译器(不管它是什么)清楚地表示“警告”。如果不存在双重定义,它是否会编译会很有趣。

以上是关于为啥我不能为 C 函数外部的全局变量赋值?的主要内容,如果未能解决你的问题,请参考以下文章

c语言中不允许在函数外部给全局变量赋值

为啥我不能为具有相同名称的命名函数表达式中的变量赋值?

c语言中,为啥不能对字符指针变量指向的字符串再赋值?

typescript怎么定义全局的函数

在C语言中能否直接给指针指向的数据赋值?为啥?

C语言——变量类型