为什么使用int的值i;未定义的行为,但使用rand()的值不是
Why is using the value of int i; undefined behaviour but using the value of rand() is not?
如果我不初始化i
,我不知道它的值,但我也无法预测rand()
的值。
但另一方面,我知道未初始化的i
的值在INT_MIN
和INT_MAX
之间,我也知道rand()
的值在0
和RAND_MAX
之间。
为什么使用未初始化的i
的值未定义行为,但使用rand()
的值不是?
未初始化变量的值为undefined。rand()
的返回值为,定义为给定种子的伪随机序列中的下一个数字。
您可以依赖于rand()
返回一个伪随机数。您不能依赖未初始化的int i
的值的任何特征。
我查阅了C99标准(ISO/IEC 9899:1999),这是我唯一可用的标准文件,但我严重怀疑这些事情已经改变了。在6.2.6类型的表示一章中,说明了整数可以用填充位存储在内存中,填充位的值未指定,但可以包含奇偶校验位,这将在初始化和对整数进行任何算术操作时设置。某些表示(例如奇偶校验不匹配)可能是陷阱表示,其行为未定义(但可能会终止您的程序)。
所以,不,你甚至不能指望一个未初始化的int i
是INT_MIN
<= i
<= INT_MAX
标准规定从未初始化的变量中读取是未定义的行为,所以它是。不能说它在INT_MIN
和INT_MAX
之间。事实上,不能认为这个变量有任何值,所以你甚至不能检验假设*。
rand()
被设计为在一个范围内产生一个随机数。如果从rand()
的结果中读取是未定义的,它将不属于任何库的一部分,因为它不能被使用。
*通常"未定义行为"提供了优化的范围。优化器可以对未初始化的变量做任何事情,假设它不是从。
定义rand
的值为(伪)随机。未初始化变量的值没有定义为任何值。这就是区别,无论什么东西被定义为有意义的东西(而rand()
也是有意义的-它给出了(伪)随机数)或未定义。
简短的回答,就像其他人说的,是因为标准是这么说的。
访问未初始化的变量值的行为(在标准中描述为执行左值到右值的转换)会产生未定义的行为。
rand()
被指定为给定0到RAND_MAX
之间的值,其中RAND_MAX
(在c++的<cstdlib>
和C的<stdlib.h>
中声明的宏)被指定为具有至少32767
的值。
考虑以下代码中的变量x
:
uint32_t blah(uint32_t q, uint32_t r)
{
uint16_t x;
if (q)
x=foo(q); // Assume return type of foo() is uint16_t
if (r)
x=bar(r); // Assume return type of bar() is uint16_t
return x;
}
由于代码永远不会给x
分配0-65535范围之外的值,32位处理器的编译器可以合法地为它分配一个32位寄存器。实际上,由于q
的值在第一次写入x
之后永远不会被使用,编译器可以使用与q
相同的寄存器来保存x
。与简单地让它返回分配给x
的寄存器中的任何内容相比,确保函数总是返回值0-65535需要添加一些额外的指令。
注意,从标准作者的角度来看,如果标准不要求编译器使x
保持0-65535之间的值,那么也可以不指定任何关于代码试图使用x
时可能发生的情况。希望在这种情况下提供任何行为保证的实现可以自由地这样做,但是标准没有强加任何要求。
rand
使用算法生成您的号码。所以rand
不是未定义的,如果当你使用srand
开始随机生成时,你选择一个像42这样的值,你每次启动你的应用程序时都会得到相同的值尝试启动这个示例,您将看到:
#include <stdio.h>
#include <stdlib.h>
int main()
{
srand(42);
printf("%dn", rand());
return 0;
}
参见:https://en.wikipedia.org/wiki/List_of_random_number_generators
- 数组索引的值没有增加
- 'short int'持有的值溢出,但"自动"不会溢出?
- 是默认情况下分配给char数组常量的值
- 这个指针和内存代码打印是什么?我不知道是打印垃圾还是如何打印我需要的值
- 为什么我无法更改"set<set>"循环中的值<int>
- 有效地使用std::unordered_map来插入或增加键的值
- <streamsize>C++ 中 numeric_limits::max() 的值
- 为什么不能修改对象中的值?另外,我如何改进此链表?
- 无法获取webot::PositionSensor对象中位置传感器的值
- 正在将无序映射设置为无序映射的值
- 在具有相同种子的同一程序中对srand()的第二次调用不会为连续的rand()生成相同的值
- Rand() 在每次函数调用时返回相同的值
- 为什么rand每次在c++中都产生相同的值
- 第一个 rand() 在 srand(time(0) 之后生成相同的值
- rand() x4000000000UL 只给出很小的值
- 为什么rand()在使用1和UINT_MAX进行种子设定时会产生相同的值
- 自定义rand()函数返回相同的值
- 为什么使用int的值i;未定义的行为,但使用rand()的值不是
- Rand()在单个函数中调用时返回相同的值
- 为什么c++ stdlib rand()函数在不同平台上对相同的种子给出不同的值?