比较有符号和无符号字符

Bik*_*eev 5 c c++ unsigned-char

看起来很奇怪。我发现误会了。我使用 gcc 和 char 作为签名字符。我一直认为,在比较表达式(和其他表达式)中,如果需要,有符号值会转换为无符号值。

int a = -4;
unsigned int b = a;
std::cout << (b == a) << std::endl; // writes 1, Ok
Run Code Online (Sandbox Code Playgroud)

但问题是

char a = -4;
unsigned char b = a;
std::cout << (b == a) << std::endl; // writes 0
Run Code Online (Sandbox Code Playgroud)

如果比较运算符不仅仅是按位,那么它的魔力是什么?

Vla*_*cow 3

根据C++标准

6 如果两个操作数都是算术或枚举类型,则对两个操作数都进行通常的算术转换;如果指定的关系为 true,则每个运算符应生成 true;如果指定的关系为 false,则每个运算符应生成 false。

所以在这个表达式中

b == a
Run Code Online (Sandbox Code Playgroud)

示例的

char a = -4;
unsigned char b = -a;
std::cout << (b == a) << std::endl; // writes 0
Run Code Online (Sandbox Code Playgroud)

两个操作数都转换为类型int。结果signed char 传播它的有符号位并且两个值变得不相等。

为了演示效果尝试运行这个简单的例子

{
    char a = -4;
    unsigned char b = -a;

    std::cout << std::hex << "a = " << ( int )a << "'\tb = " << ( int )b << std::endl;

    if ( b > a ) std::cout << "b is greater than a, that is b is positive and a is negative\n";
}
Run Code Online (Sandbox Code Playgroud)

输出是

a = fffffffc'   'b = 4
b is greater than a, that is b is positive and a is negative
Run Code Online (Sandbox Code Playgroud)

编辑:直到现在我才看到变量的定义必须看起来像

    char a = -4;
    unsigned char b = a;
Run Code Online (Sandbox Code Playgroud)

即 b 定义中的负号 a 不应出现。

  • 报价不完整。如果比较相同等级且“小于” int 的无符号和有符号类型,则有符号操作数将转换为无符号类型。 (3认同)
  • @Jeffrey:阅读“[C++11:5/9]” (2认同)
  • `char`、`signed char` 和 `unsigned char` 几乎总是通过“常规算术转换”提升为(有符号)`int`。但如果“CHAR_MAX &gt; INT_MAX”或“UCHAR_MAX &gt; INT_MAX”,则“char”或“unsigned char”将被提升为“unsigned int”。仅当“CHAR_BIT &gt;= 16”且“sizeof (int) == 1”时才会发生这种情况——并且,对于普通“char”,如果“char”恰好是无符号类型。在 8 位字节的系统上您永远不会遇到这种情况。 (2认同)