未初始化变量的值将会是什么?

7
我尝试了以下代码

可能重复:
未初始化的数据行为是否有明确定义?

我尝试了以下代码

#include<stdio.h>
void main()
{
int i; \
printf('%d',i);
}

在VC++中结果为垃圾值,而在tc中为零。正确的值是什么? 未初始化的变量默认会有零值吗?还是它将包含垃圾值?

下一个问题与此相同。

#include<stdio.h> 
void main()
{
int i,j,num;
j=(num>0?0:num*num);
printf("\n%d",j);
}

上述代码的输出结果将是什么?

它是未定义的。这就是为什么它是垃圾的。在C语言中,你必须自己初始化东西。 - Mike Dunlavey
2
哪种语言?C还是C?哦等等... - Etienne de Martel
2
你的代码输出给我的结果:http://i48.servimg.com/u/f48/11/68/36/17/nasal_10.png :-O - jrok
重新开放投票。相关的重复问题是一个C++问题,而C和C++是不同的编程语言,具有不同的规则关于未初始化变量。 - M.M
1
Stroustrup的常见问题解答链接已更改为http://www.stroustrup.com/bs_faq2.html#void-main。 - Jonathan Leffler
main() 函数返回 int 类型,并接受参数 int argcchar **argv - underscore_d
6个回答

11

从技术上讲,未初始化的非静态局部变量的值是不确定的[Ref 1]。简而言之,它可以是任何值。访问这样一个未初始化的变量会导致未定义的行为[Ref 2]

[Ref 1]
C99第6.7.8节初始化:

如果一个具有自动存储期限的对象没有被显式初始化,那么它的值是不确定的。

[Ref 2]

C99第3.18节未定义行为:

对于使用非便携或错误的程序结构、错误数据或不确定的值对象的情况,本国际标准不强制执行要求。

注意:强调是我的。


OP 询问的是 C(C89?),而不是 C++03。 - keelerjr12
1
@keelerjr12:后来重新标记了,为C99做了修改。 - Alok Save
3
为什么你会回答如此明显的骗局?我对你有更高的期望。 - sbi
1
@sbi:我一直知道我的回答的前两个语句。但我并不确定C标准的哪一部分明确说明了它们(我知道C++标准的具体规定)。我很想找到C标准的细节(是的,我对C不是很熟悉)。如果你看到我的回答编辑,我花了很多时间找到C标准明确说明这一点的确切细节。我在问题关闭后进行了编辑。这更像是我自己的学习经验,而不仅仅是提供一个答案。我承认我很自私,想要学习东西,而不仅仅是给出答案。 - Alok Save
1
@Als:你为什么要回答这样一个显而易见的复制问题?我以为你会更好。 - sbi
1
这是最不准确的,参考文献2也不相关 - 你没有引用标准中标记此UB的部分。因为标准中甚至没有任何明显的来源表明如此。请参见https://dev59.com/v2ct5IYBdhLWcg3wmOng#40674888 - Lundin

4

在C和C++中,访问未初始化的变量是未定义行为,因此可能读取任何值。

你的程序也有可能崩溃:一旦进入未定义行为领域,所有赌注都关闭1


1我从未见过一个程序因访问未初始化的变量而崩溃,除非它是一个指针。


1
对于包含陷阱表示的实现,读取任何类型(包括int)的未初始化对象可能会触发陷阱。 - Alok Save
1
需要引用。这大多是不正确的。具有陷阱表示的系统大多是虚构的,并且对于绝大多数程序来说不需要考虑。在许多情况下,访问未初始化的变量并不会调用UB。https://dev59.com/v2ct5IYBdhLWcg3wmOng - Lundin

2

这是不确定的。编译器可以随意处理。


3
说得严谨一些,它的值是不确定的;使用它会导致未定义的行为。 - Ed S.

1

该值为不定值;在初始化变量之前使用变量会导致未定义的行为。


-1

它是未定义的。它可能会因编译器、操作系统、程序不同而不同,任何情况都有可能。它甚至可能不是一个特定的值:编译器可以对这段代码进行任何喜欢的操作,因为效果没有定义。它可能选择优化您的整个程序。甚至可能选择用一个安装键盘记录器并窃取您所有在线银行登录详细信息的程序替换您的程序。

如果你想知道这个值,唯一的方法就是设置它。


-1

正如其他人所指出的,该值可以是任何东西。

这有时会导致难以发现的错误,例如因为您在调试版本中恰好获得一个值,在发布版本中获得另一个值,或者您获得的初始值取决于先前的程序执行。

教训:始终初始化变量。 C#为字段定义值并要求对局部变量进行初始化,这是有原因的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接