我知道未初始化的局部变量是未定义的行为(UB),而且值可能有陷阱表示,这可能会影响进一步的操作,但有时我想使用随机数仅为视觉表示,而不会在程序的其他部分进一步使用它们,例如,在视觉效果中设置随机颜色的东西,例如:
void updateEffect(){
for(int i=0;i<1000;i++){
int r;
int g;
int b;
star[i].setColor(r%255,g%255,b%255);
bool isVisible;
star[i].setVisible(isVisible);
}
}
比那么快吗
void updateEffect(){
for(int i=0;i<1000;i++){
star[i].setColor(rand()%255,rand()%255,rand()%255);
star[i].setVisible(rand()%2==0?true:false);
}
}
也比其他随机数生成器快吗?
好问题!
未定义并不意味着它是随机的。考虑一下,在全局未初始化变量中获得的值是由系统或您的/其他应用程序运行时遗留在那里的。根据您的系统对不再使用的内存的处理和/或系统和应用程序生成的值类型,您可能会得到:
总是一样的。
成为一小部分价值观中的一员。
获取一个或多个小范围内的值。
在16/32/64位系统的指针上看到许多可以被2/4/8整除的值
...
您将得到的值完全取决于系统和/或应用程序留下的非随机值。因此,确实会有一些噪音(除非您的系统删除不再使用的内存),但您将从中提取的值池绝不是随机的。
对于局部变量,情况会变得更糟,因为它们直接来自您自己程序的堆栈。在执行其他代码期间,您的程序很有可能实际编写这些堆栈位置。我估计在这种情况下运气的机会非常低,而你所做的“随机”代码更改将尝试这种运气。
阅读随机性。正如你所看到的,随机性是一种非常特殊且难以获得的属性。一个常见的错误是,如果你只是采取一些难以跟踪的东西(比如你的建议),你会得到一个随机的值。
正如其他人所说,这将是快速的,但不是随机的。
大多数编译器对局部变量所做的是在堆栈上为它们抓取一些空间,而不是费心将其设置为任何东西(标准说它们不需要这样做,所以为什么要减慢生成的代码呢?)
在这种情况下,你将得到的值将取决于之前在堆栈上的内容——如果你在这个函数之前调用一个有100个局部char变量设置为'Q'的函数,然后在该函数返回后调用你的函数,那么你可能会发现你的“随机”值表现得就像你已经将memset()它们全部设置为'Q'。
重要的是,你的例子函数尝试使用这个,这些值不会改变每次你读取他们,他们将是相同的每一次。所以你会得到100颗星星都设置成相同的颜色和能见度。
而且,没有什么说编译器不应该初始化这些值——所以将来的编译器可能会这样做。
总的来说:坏主意,不要做。
(就像很多“聪明的”代码级优化一样……)