很多好的回答,但请允许我补充一个并强调一点,在确定性计算机中,没有任何东西是随机的。这对伪随机数生成器产生的数字和在栈中为C / C ++本地变量保留的区域中发现的“随机”数字都是正确的。
但是......有一个关键的区别。
良好的伪随机数生成器产生的数字具有使它们在统计意义上类似于真正的随机抽样的属性。例如,分布是均匀的。周期长度很长:在循环重复之前,您可以获得数百万个随机数字。序列不是自相关的:例如,如果您看生成的数字中的每2、3或27个数字,或者如果您查看特定数字,则不会开始出现奇怪的模式。
相比之下,在堆栈上留下的“随机”数字没有这些属性。它们的值及其表面上的随机性完全取决于程序的构造方式、编译方式以及编译器的优化方式。例如,以下是将您的想法作为独立程序的变体:
#include <stdio.h>
notrandom()
{
int r, g, b;
printf("R=%d, G=%d, B=%d", r&255, g&255, b&255);
}
int main(int argc, char *argv[])
{
int i;
for (i = 0; i < 10; i++)
{
notrandom();
printf("\n");
}
return 0;
}
当我在Linux机器上使用GCC编译并运行此代码时,结果非常明显是确定性的:
R=0, G=19, B=0
R=130, G=16, B=255
R=130, G=16, B=255
R=130, G=16, B=255
R=130, G=16, B=255
R=130, G=16, B=255
R=130, G=16, B=255
R=130, G=16, B=255
R=130, G=16, B=255
R=130, G=16, B=255
如果你使用反汇编器查看编译后的代码,你可以详细地重构正在发生的事情。第一次调用 notrandom() 使用了之前该程序未使用过的堆栈区域; 谁知道那里有什么东西。但在调用 notrandom() 之后,会调用 printf()(GCC 编译器实际上将其优化为对 putchar() 的调用,但不要紧),这将覆盖堆栈。因此,在下一次和随后的调用 notrandom() 时,堆栈将包含来自执行 putchar() 的旧数据,并且由于始终使用相同的参数调用 putchar(),因此这些旧数据也始终相同。
因此,这种行为绝对没有任何随机性,而以这种方式获得的数字也没有很好编写的伪随机数生成器的任何理想特性。实际上,在大多数现实场景中,它们的值将是重复且高度相关的。
事实上,就像其他人一样,我也会认真考虑解雇试图将此想法作为“高性能 RNG”的人。