有符号和无符号字符

Signed and unsigned char

为什么 signed charunsigned char 两个具有相同值的字符不相等?

char a = 0xfb; 
unsigned char b = 0xfb;
bool f;
f = (a == b); 
cout << f;

上面代码中,f的值为0。
为什么 ab 具有相同的值?

  • (有符号)char 的取值范围是 [-128, 127]。 (C++14 将 -127 作为下限)。
  • unsigned char 的取值范围是 [0, 255]

您要分配给这两个变量的是十进制的 251。由于 char 无法保持该值,您将遭受值溢出,正如以下警告告诉您的那样。

warning: overflow in conversion from 'int' to 'char' changes value from '251' to ''777777773'' [-Woverflow]

因此 a 可能会保持值 -5b 将是 251 并且它们确实不相等。

f 的值,事实上,程序的行为,是 实现定义的

从 C++14 开始1,对于 signed char,并假设 CHAR_MAX127 , a 可能会是 -5。正式地说,如果 charsigned 并且数字不适合 char,则转换是实现定义的或引发实现定义的信号。

b251.

用于比较 a == b(并保留 char 是比 int 更窄的类型的假设) 两个 参数都被转换至 int,因此保留了 -5251

那是 false,因为数字不相等。

最后,请注意,在 charshortint 大小相同的平台上,您的代码的结果将是 true== 将是 unsigned 类型)!这个故事的寓意:不要混淆你的类型


1 C++14 去掉了 1 的补码和符号大小 signed char.

没有接受小于 int 的整数的算术运算符。因此,两个 char 值都首先提升为 int,请参阅 整体提升 了解全部详情。

char 在您的平台上签名,因此 0xfb 被提升为 int(-5),而 unsigned char 被提升为 int(0x000000fb)。这两个整数比较不相等。

另一方面,[basic.fundamental]中的标准要求所有char类型占用相同的存储量,并具有相同的对齐要求;也就是说,它们具有相同的对象表示,并且对象表示的所有位都参与值表示。因此,memcmp(&a, &b, 1) == 0true.