在C语言程序中,未初始化的局部变量值是未定义(UB,undefined behaviour)的,使用未初始化的变量可能会为程序带来意想不到的错误,这一点看过我文章的读者应该都是清楚的。
![1005ccded515abb3cffc9c88955b4461.png](https://i-blog.csdnimg.cn/blog_migrate/bc43214b8031f13d6e21e7ed761f7c30.jpeg)
使用未初始化的变量可能会为程序带来意想不到的错误
“未定义”与“随机值”
但是,反过来想一想,“未定义的”也就意味着未初始化的局部变量内部的值是不确定的,那么它能不能被当作“随机值”使用呢?例如下面这段C语言代码:
void updateEffect(){ for(int i=0;i<1000;i++){ int r, g, b; star[i].setColor(r%255,g%255,b%255); bool isVisible; star[i].setVisible(isVisible); }}
程序仅仅把未初始化的局部变量 r, g, b, isVisible 当作随机值使用,并未在其他逻辑中使用,这样做看起来要比调用 rand() 函数产生随机值效率高多了:
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); }}
![b1953b08f6144668afeeee17d6181694.png](https://i-blog.csdnimg.cn/blog_migrate/b26a61af7b367af0767cb988aeaffaba.jpeg)
未初始化的局部变量能当作“随机值”吗?
真的如此吗?
首先应该明白,计算机语言是绝对不能有歧义的,因此为C语言程序引入“未定义”的行为无疑是有违这一原则的。另外,使用未初始化局部变量作为随机值,不太可能具有理想的数学统计特性。
例如在 x86(_ 64) 架构中,从未初始化的寄存器中确实会读取出不能事先预知的值,但是这样的值并不能当作是“随机值”,因为局部变量的值存储在栈中,未初始化的值其实是栈中对应位置上一次使用者留下的。
所以如果该栈区一直没有被使用过,那么即使未初始化的局部变量也会每次都有相同的值,这显然不符合预期——产生“随机值”。换句话说,希望未初始化的局部变量提供“随机值”实在是不可靠,甚至指望它每次提供不一样的值都需要依靠运气。
![e33b8ddf71519113b997fd3f7f72a87b.png](https://i-blog.csdnimg.cn/blog_migrate/97e52defc0aac9307967050dc396d0b6.jpeg)
指望它每次提供不一样的值都需要依靠运气
即使在某段C语言代码中,未初始化的局部变量能够每次都提供不同的值,它们的数学统计特性也是不可靠的,我们不能指望它符合某种分布。
与此同时,引入“未定义”的行为到我们的C语言代码中永远是不值得推荐的做法。程序员永远都不该写不安全的代码,引入的例外越少,最终的程序就越容易避免意外错误。
因此,在C语言程序开发中,如果希望得到一个随机数,那么通过 rand() 函数获取就是最好的选择。基本上也不用担心它的效率,因为基于 rand() 函数的随机数生成器只不过是一个乘法运算,一个加法运算和一个模运算而已。
![01991ce723c092e9c8a732fd63c853a6.png](https://i-blog.csdnimg.cn/blog_migrate/32071b7016e28dda9639091f7da51674.jpeg)
通过 rand() 函数获取随机数就是最好的选择
我所知道的最快的生成器是使用 uint32_t 类型作为随机变量,并且通过下面这个表达式计算:
I = 1664525 * I + 1013904223;
I 的初始值即为所谓的随机数种子,这个表达式可以产生连续的随机数。为了尽量得到高效率的随机数生成器,内联函数和函数式宏定义都是不错的选择。
上面表达式里的两个常数,是由著名的科学程序员 Donald Knuth 手工挑选的。
小结
事实上,随机性是程序开发中非常具体,又非常难以获得的属性。把一些难以追踪的(未定义)数值当作随机值,是一种常见的错误。
![8c3fe15fa3e3e5f228d84b739859c3a8.png](https://i-blog.csdnimg.cn/blog_migrate/cd1ca405a2942b52712550f6d17453dd.jpeg)
点个赞再走吧
欢迎在评论区一起讨论,质疑。文章都是手打原创,每天最浅显的介绍C语言、linux等嵌入式开发,喜欢我的文章就关注一波吧,可以看到最新更新和之前的文章哦。
未经许可,禁止转载。