我知道未初始化的局部变量是未定义的行为(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);
}
}
也比其他随机数生成器快吗?
不,太糟糕了。
使用未初始化变量的行为在C和c++中都是未定义的,而且这样的方案不太可能具有理想的统计属性。
如果你想要一个“快速而肮脏”的随机数生成器,那么rand()是你最好的选择。在它的实现中,它所做的只是一个乘法、一个加法和一个模数。
我所知道的最快的生成器需要你使用uint32_t作为伪随机变量I的类型,并使用
I = 1664525 * I + 1013904223
生成连续的值。你可以选择任何你喜欢的I的初始值(称为种子)。显然你可以内联编码。无符号类型的标准保证包装充当模数。(数字常数是由杰出的科学程序员Donald Knuth精心挑选的。)
正如其他人所说,这将是快速的,但不是随机的。
大多数编译器对局部变量所做的是在堆栈上为它们抓取一些空间,而不是费心将其设置为任何东西(标准说它们不需要这样做,所以为什么要减慢生成的代码呢?)
在这种情况下,你将得到的值将取决于之前在堆栈上的内容——如果你在这个函数之前调用一个有100个局部char变量设置为'Q'的函数,然后在该函数返回后调用你的函数,那么你可能会发现你的“随机”值表现得就像你已经将memset()它们全部设置为'Q'。
重要的是,你的例子函数尝试使用这个,这些值不会改变每次你读取他们,他们将是相同的每一次。所以你会得到100颗星星都设置成相同的颜色和能见度。
而且,没有什么说编译器不应该初始化这些值——所以将来的编译器可能会这样做。
总的来说:坏主意,不要做。
(就像很多“聪明的”代码级优化一样……)