25.5.3 有符号数和无符号数

与大多数语言一样,C++同时支持有符号数和无符号数。无符号数在内存中的描述是很简单的:第0位表示1、第1位表示2,第2位表示4,依此类推。但是,有符号数就引出一个问题:我们如何区分正数和负数?对此,C++给了硬件设计者一定的自由选择的余地,不过几乎所有实现都使用了二进制补码表示法。最靠左的二进制位(最高有效位)被用来作为“符号位”:

如果符号位为1,就表示负数。二进制补码表示法已经成为事实上的标准方法。为了节约篇幅,我们只讨论如何在4位二进制整数中表示有符号数值:

基本思想就是:用x的位模式的补码(~x,参见25.5.1节)来表示-(x+1)的位模式。

到目前为止,我们一直在使用有符号整数(如int)。更好的程序设计原则是:

·当需要表示数值时,使用有符号数(如int)。

·当需要表示位集合时,使用无符号数(如unsigned int)。

这是一个很好的程序设计原则,但很难严格遵循,因为一些人更喜欢用无符号数进行某些算术运算,而我们有时需要用这类代码。特别是还有一些历史遗留问题,例如,在C语言历史的早期,int还是16位大小,每一位都很重要,而一个vector的大小v.size()返回的是一个无符号数。例如:

好的编译器会给出一个警告,指出存在有符号数(即i)和无符号数(即v.size())混合运算的情况。有符号数和无符号数混合运算有可能会带来灾难性的后果。例如,循环变量i可能会溢出,即,v.size()有可能比最大的有符号int值还要大。当i的值增大到有符号int所能表示的最大正数(2的幂减1,幂次等于int的二进制位数减1,如,int为16位宽度,此值为2 ...

Get C++程序设计:原理与实践(进阶篇)(原书第2版) now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.