我正在阅读有关调试的this tutorial。我在我的.c档案中粘贴了因子代码:
#include <stdio.h>
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
而不是垃圾值?
答案 0 :(得分:3)
C99 draft standard和C11 draft standard都表示未初始化的自动变量的值是不确定的,来自草案c99标准部分6.2.4
对象的存储持续时间段落 5 表示(强调我的):
对于没有可变长度数组类型的对象,其生命周期会延长 从进入与之关联的块直到该块的执行结束 无论如何。 (输入一个封闭的块或调用一个函数暂停,但不会结束, 执行当前块。)如果以递归方式输入块,则执行新的实例 每次都创建对象。 对象的初始值是不确定的。如果是 为对象指定了初始化,每次声明时都会执行初始化 在执行该块时达成;否则,每个值都变得不确定 到达声明的时间。
标准草案将不确定定义为:
未指定的值或陷阱表示
,未指定的值定义为:
本国际标准规定的相关类型的有效值 在任何情况下选择值的要求
所以价值可以是任何东西。它可能随编译器,优化设置而变化,甚至可能因运行而异,但不能依赖它,因此任何使用不确定值的程序都在调用undefined behavior。
标准规定,6.5.2.5
复合文字段 17 中的一个示例中未定义此内容,其中包含:
请注意,如果使用迭代语句而不是显式goto和带标签的语句,则未命名对象的生命周期将仅为循环体,并且在下次输入p时将具有不确定的值,< strong>会导致未定义的行为。
Annex J.2
未定义的行为:
使用具有自动存储持续时间的对象的值 不确定(6.2.4,6.7.8,6.8)。
在某些非常具体的情况下,您可以对此类行为做出一些预测,演示文稿Deep C会进入其中。这些类型的检查应仅用作进一步了解系统如何工作的工具,甚至不应接近生产系统。
答案 1 :(得分:0)
您需要将j
初始化为1.如果j
恰好为零,则答案将始终为零(一种类型的垃圾)。如果j
碰巧非零,那么你会得到不同的垃圾。使用未初始化的变量是未定义的行为; “undefined”并不排除在目前为止所做的测试中始终为零。
答案 2 :(得分:0)
某些系统的内存设置为0(例如Mac OS),因此当您初始化它时,您的变量通常会包含0,但这样做会导致不稳定的结果。
答案 3 :(得分:0)
你无法说出在这种情况下会发生什么,因为语言规范并没有说明会发生什么。事实上,它表示未初始化的非静态变量的值是不确定的。
这意味着它们可以是任何价值。它们可以在程序的不同运行中使用不同的值,或者在不同的编译器上编译代码时,或者在使用不同优化设置的同一编译器上编译时。或者在一周中的不同日期,国家法定假日或下午6点之后。
未初始化的变量甚至可以保存所谓的陷阱表示,这是一个对该类型无效的值。如果您访问这样的值,那么您就会陷入未定义行为的可怕世界,其中任何事情都可能发生。