std::rand 的文档中写道:
int rand();
返回一个介于0和RAND_MAX(包括0和RAND_MAX)之间的伪随机整数值。
由于保证返回的是非负整数,为什么返回类型是有符号的?
我不是在讨论是否应该在这里使用它。这是历史问题还是一些设计上的失误?
关于unsigned
有很多争论。不过,我们不需要深入主观领域,考虑如下:重要的不是从rand()
返回的值是否可能为负数,而是rand()
返回一个特定类型的值,该类型决定您可以对该值执行什么操作。 rand()
从不返回负值,但将对该值应用使其成为负值的操作有意义吗?当然有。例如,您可能想执行以下操作:
auto x = rand() % 6 - 3;
如果 rand()
返回一个无符号数,那么在看似正常的代码中会导致令人困惑的错误。例如,对于索引来说,使用无符号数是另一回事情。索引总是为正数。如果您要对它应用将其值变为负数的操作,那么它就不再是一个索引了。而 rand() % 6 -3
则是一个随机数,无论它是正数还是负数。类型
不仅仅是它可以表示的值的范围。有符号和无符号整数具有不同的语义。请注意,C++20 引入了 std::ssize
。它是容器的大小,它只能是正数。尽管如此,它是有符号的。这是一个例子,即使是正值也是有符号的,仅仅是为了允许有符号的算术运算。此外,将 std::size
更改为返回有符号数是不可取的,因为那样会破坏现有的代码。std::uniform_int_distribution<unsigend int>
时也可能存在相同的问题。如果我有什么错误,请纠正我。 - Nimrodstd::uniform_int_distribution<unsigned int>
时,您明确要求unsigned。小心谨慎并不是避免错误的最佳解决方案。 size()
是一个很好的例子。 当container
为空时,for (int i = container.size()-1; i>=0; --i)
看起来是正确的,但实际上它不是(循环将会出错)。作者在使用size()-1
时未明确要求unsigned,但这就是他们得到的结果。 - 463035818_is_not_a_numberchar
类型是一个16位的无符号类型。 - Bathshebachar
类型代表UTF-16代码单元,因此必须是无符号的。 - Paul Sanderschar
不适合用于算术运算。 - Ben Voigt斯特鲁普在《C++程序设计语言》第6.2.4节中写道:
* 无符号整数类型非常适合将存储视为位数组的用途。使用无符号而不是int表示正整数以获取一个更多的比特位,几乎从来都不是一个好主意。通过将变量声明为无符号以确保某些值为正数的尝试通常会被隐式转换规则所打败。
RAND_MAX
小于2的31次方(通常远小于该值),则将其声明为无符号的并没有好处,但存在一些缺点,例如如果有人执行rand() % 100 - 50
操作,则可能会得到意外的结果。 - Alan Birtlesrand()
/srand()
函数在 C 语言支持无符号(或长整型)类型之前就已经被规定了。那时候,大多数 C 语言实现都只有16位的int
类型,只有少数才有32位的int
类型,这就是为什么RAND_MAX
只需要被要求为32767(或更高)。无符号和长整型(以及其他一些类型)是在 Unix 被用 C 重写(1973年)时引入的。随后的 C 语言进化(包括 C89 标准)保持向后兼容,并且根据 ARM 的说法,第一个 C++ 标准也要尽可能地保持与 C89 的兼容性。 - Peter