【问题标题】:Why default value of local variables in C is same?为什么C中局部变量的默认值相同?
【发布时间】:2013-06-30 16:17:40
【问题描述】:
#include <stdio.h>  
int main()
{
    int i,j=3;
    i=4+2*j/i-1;
    printf("%d",i);
    return 0;
}

每次都会打印 9,虽然 i 没有初始化, 所以, 它必须打印任何垃圾值。 请解释...

【问题讨论】:

  • “每次都会打印 9” 也许在一个特定的环境中使用一个特定的编译器,但不是一般的。
  • 对我来说,它每次打印 3。它是特定于工具链的...顺便说一句,我已经看到 malloc 的实现,即使标准不需要它,默认内存为 0。
  • 会的 --- no it won't.
  • Floating point exception 为我 :)
  • 请解释否决票

标签: c local-variables


【解决方案1】:

C 中未初始化的局部变量的值是不确定的,读取它会引发未定义的行为。

现在,在特定环境中重复执行特定程序特定编译器编译(就像你正在做的那样)可能会产生相同的(当然,仍然是未定义的)行为。这可能是因为操作系统通常会在您每次运行时为您的进程提供相同范围的逻辑内存,因此您的程序读取的垃圾很有可能每次都相同(但它仍然是垃圾)。或者可能是因为编译器甚至懒得给你将要阅读的垃圾的二进制表示,而是给你别的东西(只要它不违反标准)。

【讨论】:

  • Sssssssssshhhh。有礼貌,伙计们!
  • 删除所有内容似乎不是最合适的解决方案。
【解决方案2】:

您的代码将生成Undefined Behavior。未定义行为是指行为不可预测的计算机代码。代码的输出取决于编译器、环境。

【讨论】:

    【解决方案3】:

    http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf 是 C 编程语言的国际标准

    Page No : 126
    
    Heading : Semantics
    
    Item No : 10
    

    引用自此

    如果具有自动存储持续时间的对象未初始化 明确地说,它的值是不确定的。

    这必须回答你的问题。

    编辑:@Jens Gustedt 在 cmets 中建议

    6.3.2.1, p2, 表示如果左值指定了一个可以用寄存器声明的自动存储持续时间的对象 存储类(从未获取过它的地址),并且该对象是 未初始化(未使用初始化程序声明且未分配给 它已在使用前执行),行为未定义。

    【讨论】:

    • 官方标准是C11,文档1570。而你引用的这个部分是不够的。 6.3.2.1,p2,说 如果左值指定了一个可以用寄存器存储类声明的具有自动存储持续时间的对象(从未使用过它的地址),并且该对象未初始化(未使用初始化程序和在使用之前没有对其进行分配),行为是未定义的。
    • @JensGustedt 谢谢。更新了答案
    • 这是否意味着如果一个自动变量的地址确实被占用但从未被写入,它可以安全地被多次读取并保证每次都包含相同的值,而不会调用未定义的行为?这是否适用于大于char 的类型?
    • @JensGustedt 这有点跑题了,但是你知道我可以在任何地方找到 C99 和 C11 之间的差异列表和/或 N1570 和官方最终 C11 之间的差异列表吗?跨度>
    • @Zack,在委员会open-std.org/jtc1/sc22/wg14/www/docs 的网站上,您会发现 pdf 与以前的草稿等有所不同。 n1570 本身就有这样的差异标记。可能您可以在那里找到哪些与应该发布的邮件不同。 n1570和最终版的区别基本上就是去掉了这个diff标记。标准中已经有一个 TC,它只指定了 __STDC_VERSION__201112L 的值,之前被遗忘了。
    【解决方案4】:

    当一个变量在初始化之前被使用时,它会从内存中获取一个垃圾值。
    垃圾值是最后存储在为该变量保留的内存位置中的值(在本例中为i)。

    当您编译程序时,每次它都会从该内存位置获取先前存储的值,并会导致未定义的行为。
    没有必要每次都给出输出9。使用不同的编译器编译时,程序的行为可能会有所不同。

    【讨论】:

    • 嗯,不一定,但在 GNU C 编译器的情况下,我相信这是真的。变量有一个地址,它的值就是那个内存位置已经存在的值。
    • 我没有否决你,伙计。事实上,我现在要对你投赞成票,因为投反对票太苛刻了。
    • @Noldorin;我已经编辑了关于您的第一条评论的帖子。以及否决票的原因.......?是反对选民
    猜你喜欢
    • 1970-01-01
    • 2014-02-08
    • 2013-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多