有符号/无符号不匹配比较

问题描述

#include <stdio.h>
int main()
{
    int a = -2;         // 0xFFFFFFFE
    unsigned int b = 1; // 0x00000001

    if ((int)a > (int)b) printf("(int)a > (int)b;\n");
    else printf("(int)a < (int)b;\n");

    if ((unsigned int)a > (unsigned int)b) printf("(unsigned int)a > (unsigned int)b;\n");
    else printf("(unsigned int)a < (unsigned int)b;\n");

    if (a > b) printf("a > b;\n");
    else printf("a < b;\n");

    char c = -2;         // 0xFE
    unsigned char d = 1; // 0x01

    if ((char)c > (char)b) printf("(char)c > (char)d;\n");
    else printf("(char)c < (char)d;\n");

    if ((unsigned char)c > (unsigned char)d) printf("(unsigned char)c > (unsigned char)d;\n");
    else printf("(unsigned char)c < (unsigned char)d;\n");

    if (c > d) printf("c > d;\n");
    else printf("c < d;\n");

    return 0;
}


run result is:
(int)a < (int)b;
(unsigned int)a > (unsigned int)b;
a > b;
(char)c < (char)d;
(unsigned char)c > (unsigned char)d;
c < d;

为什么 a> b c ?那么默认的编译器标尺是什么? 我本来以为编译器会将所有数字都转换为 int 类型,但这令我感到困惑。

解决方法

为什么是a> b

当同一类型 rank 的两种类型(根据需要通常升级为int/unsigned之后)的符号不同时,有符号类型将转换为无符号类型。

int a = -2;
unsigned int b = 1;
if (a > b)
if ((unsigned)a > b)   // convert int to unsigned
if ((unsigned)-1 > 2)  // convert int to unsigned
if (UINT_MAX > 2)

为什么c

在给定int/unsigned的情况下,通常升迁到char是带有签名的 char

char c = -2;        
unsigned char d = 1;
if ((int)c > (int)d)  // promote char to int
if ((int)-2 > (int)1)
if (-2 > 1)

曾经char unsigned char

char c = -2; // c takes on the value of CHAR_MAX + 1 - 2 (254)
char c = 254;        
unsigned char d = 1;
if ((int)c > (int)d)  // promote char to int
if ((int)254 > (int)1)
if (254 > 1)
,

这遵循Usual arithmetic conversions的C规则。

关系运算符, =,==,!=
...
4)否则,两个操作数都是整数。两个操作数都进行整数提升(请参见下文);然后,在整数提升之后,将出现以下情况之一: 如果类型相同,则该类型为普通类型。

否则(类型不同):如果类型具有相同的符号性(带符号或无符号),则类型具有较小转换等级(请参见下文)的操作数将隐式转换为其他类型。 / p>

否则(符号性质不同):如果无符号类型的转换等级大于或等于有符号类型的等级,则具有带符号类型的操作数将隐式转换为无符号类型

否则(有符号性不同,并且无符号类型的转换等级小于有符号类型):如果有符号类型可以表示无符号类型的所有值,那么具有无符号类型的操作数将隐式转换为有符号类型类型。

否则,两个操作数都将隐式转换为有符号操作数类型的无符号类型对应物。

例如,a > b的情况在上方突出显示:操作数具有相同的int类型,但符号不同。 int不能覆盖unsigned int值的整个范围(在通常的实现中,大概包括OP),因此unsigned类型的转换排名int,并且比较以(unsigned)a > b完成。其他情况遵循相同的规则。

,

由于“通常的算术转换”,signed int将在进行比较之前转换为unsigned int

有关“常规算术转换”的更多信息:C in a Nutshell

否则,一个操作数的符号类型为T,其转换等级为 高于其他操作数类型。另一个操作数是 仅当类型T能够代表所有类型时,才转换为类型T 其先前类型的值。如果不是,则两个操作数都将转换 到与有符号类型T对应的无符号类型。

以下代码行包含一些示例:

int i = -1;
unsigned int limit = 200U;
long n = 30L;

if ( i < limit )
  x = limit * n;

在此示例中,要在if条件下评估比较,必须首先将i的值-1转换为 键入unsigned int。结果是一个很大的正数。在32位上 系统,该数字为2 ^ 32 − 1,在任何系统上,该数字都大于 limit。因此,如果条件为假。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...