【发布时间】:2009-08-04 05:24:31
【问题描述】:
在 C 中,自动变量如果未初始化,则保存一个垃圾值。但是,请考虑以下程序:
int main(){
signed char term;
(char)term--;
printf("%d\n",term);
}
它打印一个值'7'。如果我不做(char)term--,它会打印一个值'8'。所以,它绝对没有垃圾值。这不矛盾吗?
【问题讨论】:
在 C 中,自动变量如果未初始化,则保存一个垃圾值。但是,请考虑以下程序:
int main(){
signed char term;
(char)term--;
printf("%d\n",term);
}
它打印一个值'7'。如果我不做(char)term--,它会打印一个值'8'。所以,它绝对没有垃圾值。这不矛盾吗?
【问题讨论】:
那是垃圾。你得到 8 作为垃圾,减去得到 7。
这就是未定义的行为。仅仅因为你不断得到 8 并不意味着它是明确定义的。尝试在你的代码中做更复杂的事情。在char 的上方和下方添加变量。
关于你的“测试”,你说:
但是,考虑到垃圾应该是随机的,一致性很难被忽视。
您需要检查您的假设。 “垃圾应该是随机的”是谁说的?垃圾应该根据什么随机?垃圾是随机的唯一方法是系统定期遍历内存并为其分配随机数。
当我们说“随机”时,我们的意思是我们不知道它会是什么。这并不意味着它是不确定的。这些是计算机。如果你告诉他们一遍又一遍地做同样的事情,它会一遍又一遍地做同样的事情。
您的编译器和设置不断生成相同的代码,最终为您提供这些垃圾值。确定性,但您不能依赖这种行为:“随机”。
另外,1-800 并不意味着你要像以前那样接受这个。 “8”不一定表示垃圾,因为在设置事物的方式中,您的编译器会用 8 填充它们。他的意思是 8 与任何其他数字一样垃圾。
【讨论】:
值 8 包含在被认为是“垃圾”或“未初始化”的数字集中。
【讨论】:
就值而言,垃圾是某些先前函数留在堆栈中的任何内容。更改 libc 或任何数量的东西,这个数量就会改变。
【讨论】:
您似乎混淆了“垃圾”和“非确定性”这两个术语。术语中的值被认为是垃圾,因为您无法控制其中的值。它可以从平台更改为平台或运行运行,即未定义的行为..
另一方面,如果程序运行时环境中的所有东西都相等,那么每次运行的值可能都相同。然而,这并不排除它是垃圾。
【讨论】:
它确实包含垃圾,它包含 8 位垃圾,并将二进制读取为 0-255 之间的数字(假装您使用无符号字符)。
所以记忆可能是这样的:
| 0 0 1 0 1 0 1 0 0 1 0 0 1 0 0 1 0 1 0 1 |
它取了结尾 (1 0 0 1 0 1 0 1) 并将其读取为一个数字,即 149。它仅取决于指定长度的位置中的随机二进制文件(例如:unsigned char = 1个字节)
如果它是一个无符号整数,它会占用 4 个字节的随机垃圾并使其成为一个数字。
【讨论】:
将其视为使用任意值(位模式)进行初始化。
那个任意值取决于变量最后一次使用的堆栈位置,它绝对不是随机值。它可能总是也可能不总是相同的值。它可能取决于之前发生的任何其他事情。
最好始终初始化自动变量以避免未定义的行为。
【讨论】:
感谢您的回答。我尝试了一点修改:
int main(){
signed char term1;
signed char term2;
signed char term3;
printf("%d\n%d\n%d\n",term1,term2,term3);
}
我在 3 台不同的机器上运行该程序。结果在所有 3 台机器上都是相同的:term1 的值 = -124,term2 = 4 和 term3 = 8。如果我删除 term3,term1 = 4,term2 = 8。如果我删除 term2,term1 = 8。所以,基本上,最后一个被标记为有符号字符的值得到“8”的值。正如1800 INFORMATION所说,'8'是用来表示垃圾的值之一,可能就是这样。然而,考虑到垃圾应该是随机的,一致性是很难忽视的。
【讨论】: