看起来很奇怪。我发现了误解。我使用带有char的gcc作为signed char。我一直认为,在比较表达式(和其他表达式)中,如果需要,有符号值将转换为无符号。
int a = -4;
unsigned int b = a;
std::cout << (b == a) << std::endl; // writes 1, Ok
但问题在于
char a = -4;
unsigned char b = a;
std::cout << (b == a) << std::endl; // writes 0
比较运算符的神奇之处在于它不仅仅是按位吗?
答案 0 :(得分:3)
由于(unsigned) int
的宽度至少为16位,因此我们将其用于教学目的:
在第一种情况下:a = 0xfffc
和b = (unsigned int) (a) = 0xfffc
在arithmetic conversion rules之后,比较评估为:
((unsigned int) b == (unsigned int) a)
或(0xfffc == 0xfffc)
,即(1)
在第二种情况下:a = 0xfc
和b = (unsigned char) ((int) a)
或:
b = (unsigned char) (0xfffc) = 0xfc
即签名延伸至(int)
并截断
由于和int
可以表示signed char
和unsigned char
类型的范围,因此比较评估为:(零扩展与符号扩展)< / em>的
((int) b == (int) a)
或(0x00fc == 0xfffc)
,即(0)
。
答案 1 :(得分:2)
根据C ++标准
6如果两个操作数都是算术或枚举类型,则通常 对两个操作数执行算术转换;每一个 如果指定的关系为真,则运算符应为真 如果是假的,则为false。
所以在这个表达式中
b == a
示例
char a = -4;
unsigned char b = -a;
std::cout << (b == a) << std::endl; // writes 0
两个操作数都转换为int
类型。结果签名char propagets其签名位和两个值变得不相等。
要演示效果,请尝试运行此简单示例
{
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";
}
输出
a = fffffffc' 'b = 4
b is greater than a, that is b is positive and a is negative
编辑:只是现在我已经看到变量的定义必须看起来像
char a = -4;
unsigned char b = a;
这是b定义中的减号,不存在。
答案 2 :(得分:0)
他们都output 0
,因为无符号值可以转换为有符号值,而不是反之亦然(就像你说的那样)。