C中的无符号和有符号值

she*_*ngy 2 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");
}
Run Code Online (Sandbox Code Playgroud)

我在VC6 SP6中尝试了这个代码,字符串没有输出.一切看起来都很好,因为我们都知道-1被翻译为255.

但是当我读到"Expert C Programming Deep C Secrets"一书1.10时

它说如果我的编译器使用ANSI C标准,则此代码将打印"-1 <(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");    
}
Run Code Online (Sandbox Code Playgroud)

我得到的输出是:-1 <(unsigned char)1:ANSI.

我正在使用VC6 SP6编译器.

为什么会这样?

根据"计算机系统:程序员的视角"一书

-1 <(unsigned char)1将-1转换为无符号值.所以它会变成这样的:

255 <1

这不应该打印出行-1 <(unsigned char)1:ANSI.

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

Arm*_*yan 12

if(-1 < (unsigned char)1)

在这种情况下,两个操作数都被提升为int.

if( -1 < 0u )

在这种情况下,两个操作数都转换为unsigned int.

以下引用证明我是对的.

许多期望算术或枚举类型的操作数的二元运算符会以类似的方式引起转换并产生结果类型.目的是产生一个通用类型,它也是结果的类型.此模式称为通常的算术转换,其定义如下:
- 如果任一操作数的类型为long double,则另一个操作数应转换为long double.
- 否则,如果任一操作数为double,则另一个操作数应转换为double.
- 否则,如果任一操作数是浮点数,则另一个操作数应转换为浮点数.
- 否则,应对两个操作数执行整数提升(4.5).54)
- 然后,如果任一操作数为无符号长,则另一个操作数应转换为无符号长整数.
- 否则,如果一个操作数是long int而另一个是unsigned int,那么如果long int可以表示unsigned int的所有值,则unsigned int应该转换为long int; 否则两个操作数都应转换为unsigned long int.
- 否则,如果任一操作数很长,另一个操作数应转换为long.
- 否则,如果任一操作数是无符号的,则另一个操作数应转换为无符号.[注意:否则,唯一剩下的情况是两个操作数都是int]

而这(整体促销):

如果int可以表示源类型的所有值,则可以将char,signed char,unsigned char,short int或unsigned short int类型的rvalue转换为int类型的rvalue.否则,源rvalue可以转换为unsigned int类型的rvalue.

说实话,引用来自C++ 03标准,但它们也适用于C语言.