非初始化变量的默认值

我正在阅读有关调试的本教程 。 我在我的.c档案中粘贴了因子代码:

#include  int main() { int i, num, j; printf ("Enter the number: "); scanf ("%d", &num ); for (i=1; i<num; i++) j=j*i; printf("The factorial of %d is %d\n",num,j); } 

当我运行可执行文件时,它总是打印0 ,但是,教程的作者说它返回数字垃圾值。 我已经用Google搜索了这个,我读过这是正确的,除了静态变量。 所以它应该返回一个垃圾数而不是0

我认为这可能是由于不同版本的C,但指南是从2010年开始。

为什么我总是看到0而不是垃圾值?

C99标准草案和C11标准草案都说未初始化的自动变量的值是不确定的,来自草案c99标准第6.2.45的对象的存储持续时间表示( 强调我的 ):

对于没有可变长度数组类型的此类对象,其生命周期从entry进入与其关联的块,直到该块的执行以任何方式结束。 (输入一个封闭的块或调用一个函数会暂停,但不会结束当前块的执行。)如果以递归方式输入该块,则每次都会创建一个新的对象实例。 对象的初始值是不确定的。 如果为对象指定了初始化,则每次在执行块时达到声明时都会执行初始化; 否则,每次达到声明时,该值将变为不确定。

标准草案将不确定定义为:

要么是未指定的值,要么是陷阱表示

并且未指定的值定义为:

本国际标准对在任何情况下选择的值没有要求的相关类型的有效值

所以价值可以是任何东西。 它可能随编译器,优化设置而变化,甚至可能因运行而异,但不能依赖它,因此任何使用不确定值的程序都会调用未定义的行为 。

标准说这在6.5.2.5 复合文字17段中的一个例子中未定义,其中说:

请注意,如果使用迭代语句而不是显式goto和带标签的语句,则未命名对象的生命周期将仅为循环体,并且在下一次输入p时将具有不确定值, 这将导致未定义的行为。

这也包含在Annex J.2 未定义的行为

具有自动存储持续时间的对象的值在不确定时使用(6.2.4,6.7.8,6.8)。

在某些非常具体的情况下,您可以对此类行为做出一些预测, Deep C将介绍其中的一些行为。 这些类型的检查应仅用作进一步了解系统如何工作的工具,甚至不应接近生产系统。

您需要将j初始化为1.如果j恰好为零,则答案将始终为零(一种类型的垃圾)。 如果j恰好非零,你会得到不同的垃圾。 使用未初始化的变量是未定义的行为; ‘undefined’并不排除在目前为止所做的测试中始终为零。

有些系统将其内存设置为0(例如Mac OS),因此当您初始化它时,您的变量通常会包含0,但这会导致不稳定的结果。

你不能说在这种情况下会发生什么,因为语言规范没有说明会发生什么。 实际上它表示未初始化的非静态变量的值是不确定的。

这意味着它们可以是任何价值。 它们在程序的不同运行中可以是不同的值,或者在不同的编译器上编译代码时,或者在使用不同优化设置的同一编译器上编译时。 或者在一周的不同日期,国家法定假日或下午6点之后。

未初始化的变量甚至可以保存所谓的陷阱表示,这是一个对该类型无效的值。 如果你访问这样一个值,那么你就会陷入未定义行为的可怕世界,其中任何事情都可能发生。