C中的无符号和有符号值

时间:2011-07-23 10:29:11

标签: c unsigned signed

这是一个问题:

在书'计算机系统:程序员的视角'一节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。

任何人都可以告诉我为什么会这样吗?

1 个答案:

答案 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.