【问题标题】:Can anyone please explain me why this prints 41? [duplicate]谁能解释一下为什么会打印 41? [复制]
【发布时间】:2017-11-12 02:53:16
【问题描述】:

所以这段程序编译并运行良好。但我不明白为什么它打印出 41。因为变量不是全局的。它们是函数的局部变量。

为了澄清起见,我以两种不同的方法更改变量名称。变量名相同与结果无关。

#include<stdio.h>

    void init();
    void _print(); 

    int main(){
        init();
        _print(); 
    }

    void init(){
       int myVar;
       myVar = 41; 
    } 

    void _print(){
       int xyz;
       printf("%d",xyz); 
    }

【问题讨论】:

  • 我会稍微研究一下头部和堆栈内存分配以及它们是如何工作的。我没有足够的知识来给出明确的答案,但基本上,由于第二个变量已初始化,它指向第一个变量并读取第一个变量的值。如果您以不同的方式命名变量或更改类型,您仍然会得到一致的结果(这里没有随机的东西或“魔法”)。如果你使用 valgrind 来检查程序,它会告诉你执行它的时候有错误。
  • 我会这样做@MatthieuRaynauddeFitte。谢谢

标签: c scope logic


【解决方案1】:

在这里您正在访问垃圾值。垃圾值原来是41。您下次运行它或某天来信您可能会得到不同的结果。最初在_print() 函数的myVar 中的值是41。更准确地说,myVar 得到的那块内存包含41。(作为可能原因的解释)之前对init() 函数的调用用41 初始化了一个变量,当调用结束时,仍然是 41在记忆中。下次你会得到那个值。

访问未初始化的值是未定义的行为。

【讨论】:

  • @metadata.: 是的,它只是一些垃圾值。您可以多次运行它或做任何事情,而不是每次都会得到相同的结果。访问未初始化的值是未定义的行为。
  • 如果它是随机的,你每次都会得到不同的值,但你没有。是一致的
  • 这就是我的观点,如果我将 41 更改为 78 之类的其他值,它会打印出 78,即使我在两个不同的函数中使变量名称不同,我也不会得到随机值。它仍然从 init 函数中打印出值。奇怪。
  • 感谢@coderredoc 我认为现在有意义。
  • @MatthieuRaynauddeFitte.:如果我们认为对函数的调用是使用堆栈帧实现的,那么对函数的第一次调用会推送一个堆栈帧,并将值 41 分配给一个变量。然后它被弹出。然后再次调用具有相同数量的局部变量的函数。但是内存仍然包含先前的 41 值。这就是它得到它的原因。
【解决方案2】:

就像你说的,变量是每个函数的本地变量。 42 恰好是您的内存中的值,它在您的 _print() 函数中分配给 myVar。 是垃圾价值。

【讨论】:

  • 即使我用两种不同的方法更改变量的名称。它仍然打印 41。我不明白为什么 void init(){ int myVar;我的变量 = 41; } 无效 _print(){ int Var; printf("%d",Var); }
  • 是的。这并不一定意味着什么。
  • 很确定这与堆和堆栈的使用有关。此外,您应该以不同的方式从 _print() 方法中使用“myVar”。它产生相同的结果,并且更容易理解。
  • 我记得我的教授过去总是强调必须始终初始化 C 中的变量。
  • 他们会这样做,否则他们倾向于在未定义的位置阅读。在这种情况下,由于代码很小,它看起来像是第一个变量。你也可以通过改变第一个值的类型来测试它,你仍然会得到一致的结果
【解决方案3】:

来自C Standards#6.7.9p10

如果具有自动存储持续时间的对象未显式初始化,则其值是不确定的。

在 C 语言中,非静态局部变量没有默认值。在从堆栈分配变量的存储空间之前,该变量保存了该内存位置上发生的任何垃圾。

您为未初始化变量xyz 获得的值41 是垃圾值。

【讨论】:

    猜你喜欢
    • 2020-06-17
    • 2014-05-30
    • 1970-01-01
    • 2015-08-23
    • 1970-01-01
    • 1970-01-01
    • 2015-07-06
    • 2011-12-12
    • 2015-01-06
    相关资源
    最近更新 更多