这是一个问题:
在书'计算机系统:程序员的视角'一节2.2.5
它表示如果无符号值与有符号值进行比较,则将以非换行格式比较所有值。像这样
if(-1 < 0u)
{
// will not print this line because -1 will be translated to 255.
printf("all changed to unsigned format");
}
我在VC6 SP6中尝试了这个代码,字符串没有输出。一切看起来都很好,因为我们都知道-1被翻译为255。
但是当我读到“Expert C Programming Deep C Secrets”一书1.10
时它说如果我的编译器使用ANSI C标准,则此代码将打印“-1&lt;(unsigned char)1:ANSI”:
if(-1 < (unsigned char)1)
{
printf("-1 < (unsigned char)1: ANSI");
}
else
{
printf("-1 NOT Less than (unsigned char)1: K&R");
}
我得到的输出是:-1&lt; (unsigned char)1:ANSI。
我正在使用VC6 SP6编译器。
为什么会发生这种情况?
根据“计算机系统:程序员的观点”一书
-1&lt; (unsigned char)1将-1转换为无符号值。所以它会变成这样的:
255&lt; 1
这不应该打印出行-1&lt; (unsigned char)1:ANSI。
任何人都可以告诉我为什么会这样吗?
答案 0 :(得分:12)
if(-1 < (unsigned char)1)
在这种情况下,两个操作数都被提升为int
。
if( -1 < 0u )
在这种情况下,两个操作数都转换为unsigned int
。
以下引用证明我是对的。
许多期望算术或算术操作数的二元运算符 枚举类型导致转换并产生类似的结果类型 办法。目的是产生一种普通类型,它也是一种类型 结果。这种模式称为通常的算术转换, 其定义如下:
- 如果任一操作数的类型为long 双倍,另一个应转换为长双。
- 否则,如果 操作数是双精度,另一个是转换为双精度。
- 否则,如果任一操作数是浮点数,则另一个操作数应转换为 浮动。
- 否则,应执行整体促销(4.5) 在两个操作数上.54)
- 然后,如果任一操作数是无符号长的 其他应转换为无符号长。
- 否则,如果是一个操作数 是一个long int和另一个unsigned int,那么如果long int可以 表示unsigned int的所有值,unsigned int应为 转换为long int;否则两个操作数都应转换为 unsigned long int。
- 否则,如果任一操作数很长,则另一个操作数 应转换为长期。
- 否则,如果任一操作数是 无符号,另一个应转换为无符号。 [注意:否则, 唯一剩下的情况是两个操作数都是int]
这个( 整体促销 ):
char类型的rvalue,signed char,unsigned char,short int或 如果是int,unsigned short int可以转换为int类型的rvalue 可以表示源类型的所有值;否则,来源 rvalue可以转换为unsigned int类型的右值。
说实话,引用来自C ++ 03标准,但它们也适用于C.