当前位置: 首页 > 知识库问答 >
问题:

C中未初始化的变量行为

汪迪
2023-03-14

我已经检查过自己,我写了一个这样的程序

int main() {
 int i;
 cout << i;
 return 0;
}

我运行了几次程序,结果始终是一样的,零。我在C中尝试过,结果是一样的。

但我的教科书说

如果未初始化函数内定义的变量,则该变量值将保持未定义状态。这意味着该元素具有以前驻留在内存中该位置的任何值。

当程序始终将可用内存位置分配给变量时,这怎么可能?它怎么可能是零以外的东西(我假设默认的可用内存值为零)?

共有3个答案

施招
2023-03-14

代码调用未定义的行为(UB),因为变量是未初始化使用的。

当使用警告标志时,编译器应该发出警告,例如 -Wall

warning: 'i' is used uninitialized in this function [-Wuninitialized]
  cout << i;
          ^

碰巧的是,在您的系统上,在这次运行中,它的值为0。这意味着分配给变量的垃圾值恰好为0,因为那里的内存剩余部分表明了这一点。

但是,请注意,内核零相对频繁地出现。这意味着我可以得到零作为我的系统的输出是很常见的,但它不能保证,不应该被带入promise。

岳出野
2023-03-14

如果您不初始化在函数中定义的变量,则变量值仍未定义。

这是真的。

这意味着该元素具有以前驻留在内存中该位置的任何值。

这位不是。

有时在实践中会发生这种情况,你应该意识到,对于你的程序的任何给定的运行,得到零或不得到零完全符合这个理论。

理论上,如果您的编译器愿意,它实际上可以为该整数分配一个随机初始值,因此试图合理化这一点是完全没有意义的。但是让我们继续假设“元素接受以前驻留在内存中该位置的任何值”...

它怎么可能是零而不是零(我假设默认的可用内存值为零)?

好吧,这就是当你假设的时候会发生什么。:)

宋健柏
2023-03-14

当程序总是为变量分配一个可用内存位置时,这怎么可能呢?它怎么可能是什么而不是零?

让我们来看一个示例实际实现。

假设它使用堆栈来保留局部变量。

void
foo(void)
{
        int foo_var = 42;
}

void
bar(void)
{
        int bar_var;
        printf("%d\n", bar_var);
}

int
main(void)
{
        bar();
        foo();
        bar();
}

上面完全错误的代码说明了这一点。在我们调用foo后,堆栈上放置foo_var的某个位置设置为42。当我们调用bar时,bar_var占据了该确切位置。事实上,执行代码会导致打印0和42,表明除非初始化,否则无法依赖bar_var值。

现在应该清楚,需要局部变量初始化。但main会是一个例外吗?是否有任何东西会影响堆栈并最终给我们一个非零值?

是的。main 不是程序中执行的第一个函数。事实上,设置所有内容需要大量的工作。任何这些工作都可以使用堆栈并在其上留下一些非零。您不仅可以期望在不同的操作系统上具有相同的值,而且在您现在正在使用的系统上,它很可能会突然发生变化。有兴趣的各方可以在谷歌上搜索“动态链接器”。

最后,C语言标准甚至没有术语栈。为局部变量留一个“位置”是留给编译器的。它甚至可以从给定的寄存器中随机获取垃圾。它真的可以是任何东西。事实上,如果一个未定义的行为被触发,编译器可以随心所欲。

 类似资料:
  • 本文向大家介绍tensorflow 初始化未初始化的变量实例,包括了tensorflow 初始化未初始化的变量实例的使用技巧和注意事项,需要的朋友参考一下 今日在Stack Overflow上看到一个问如何只初始化未初始化的变量,有人提供了一个函数,特地粘贴过来共大家品鉴: 通过tf.global_variables()返回一个全局变量的列表global_vars, 然后以python列表解析式的

  • 我在这里看到过类似的问题,如果这看起来像是重复的,我很抱歉,但是类似问题的答案对我没有帮助。所以我有一个方法,它是类的一部分。这里是: 错误表明变量min可能尚未初始化。我不明白这怎么可能是真的。我觉得变量不可能不在for循环之外初始化。请帮忙。谢谢

  • 我有以下Java代码: 但是,当我运行它时,它会抛出以下错误: 我在do之前初始化了变量。while 循环,并在 try. 中设置值。捕获循环。似乎尚未设置该变量。抱歉,如果这是一个相当基本的问题,但我似乎无法弄清楚。

  • 问题内容: 我的Java程序中出现以下错误: Java变量未初始化错误…错误:变量nam和r未初始化位置类子级 但是并且已经初始化,但是我仍然遇到相同的错误。 问题答案: 不要获取 默认值 ,应在使用它们之前对其进行初始化,并使用main中的默认值进行初始化,这样就可以了。 顺便说一句,考虑为您的类和变量命名是有意义的。

  • 问题内容: 我有一个方法创建一个,另一个方法更改字符串 我的编译器说它“可能尚未初始化”。 有人可以解释吗? 问题答案: 变量可能尚未初始化 在内部定义方法时,必须在其中初始化程序的每个变量中必须先使用一个值的地方。 同样重要的是,您的代码将永远无法正常运行,因为Java中的字符串是不可变的,因此您无法编辑字符串,因此应更改方法。 我将您的代码更改为类似的内容,但是我认为您的编辑方法应该做另一件事