【问题标题】:Signed and unsigned char有符号和无符号字符
【发布时间】:2019-01-15 20:48:33
【问题描述】:

为什么signed charunsigned char这样的两个char值相同的不相等?

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

以上代码中f的值为0。
ab 具有相同的值时,为什么会这样?

【问题讨论】:

  • 你在编译器中看到过这个警告吗? warning: overflow in conversion from 'int' to 'char' changes value from '251' to ''\37777777773'' [-Woverflow] char a=0xfb;see here.
  • 我的代码在没有任何警告的情况下运行并且输出为 0;
  • 尝试启用警告。 a 的值为 -5b 的值为251。它们不相等。
  • @Bathsheba 我认为深入了解语言律师细节对 OP 没有帮助。让我们尝试解释观察到的行为。
  • @RaymondChen:垃圾。在这里选择答案是合适的。我真的不明白你的意思。不要 (i) 对 OP 做出假设,并且 (ii) 不要假设整个页面都针对 OP。你上面的评论是无知的。我可以访问一台机器,其中 char、short、int、long 和 long long 的大小都相同。

标签: c++ unsigned-char


【解决方案1】:
  • (签名的)char 的值范围是 [-128, 127]。 (C++14 将 -127 作为下限)。
  • unsigned char 的取值范围是[0, 255]

您尝试分配给这两个变量的是十进制的251。由于char 无法保存该值,您将遭受值溢出,如下警告所示。

警告:从 'int' 到 'char' 的转换溢出将值从 '251' 更改为 ''\37777777773'' [-Woverflow]

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

【讨论】:

  • 但在输出时 a 和 b 都打印相同的符号。
  • @T.g 字符类型的打印机制解释底层位模式,而不是变量的数值。表示相同,但​​值不同。
  • @molbdnilo 谢谢,我明白了...但是如何将值 -5 分配给 ..因为 251 不在 [-128,127] 的范围内
  • @T.g 我刚刚在另一个答案下问过同样的问题:) 看看这个:stackoverflow.com/a/1049880/509868
【解决方案2】:

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

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

b251

为了比较a == b(并保留char 是比int 更窄的类型的假设)两个 参数都转换为int-5 和@ 987654339@因此保留。

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

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


1 C++14 去掉了 1 的补码并带符号幅度signed char

【讨论】:

  • 为什么是-5?我这样计算 -3:-127 + (251 - 127)。这不正确吗?
  • @pergy。不,2 的补码不能那样工作。这是-5。
  • stackoverflow.com/a/1049880/509868 (实际上,该答案以值 -5 为例)
  • @anatolyg:你不能比这更好!
  • “C++14 去掉了 1 的补码和有符号的幅度有符号字符”。我检查了当前的草案标准,但没有找到。这是明确表示的,还是可以推断出来的?
【解决方案3】:

没有接受小于int 的整数的算术运算符。因此,两个 char 值首先被提升为 int,详情请参阅 integral promotion

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-01-28
    • 1970-01-01
    • 2010-09-30
    • 1970-01-01
    • 1970-01-01
    • 2021-10-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多