我正在尝试将无符号整数与有符号字符进行比较,就像这样:
int main(){
unsigned int x = 9;
signed char y = -1;
x < y ? printf("s") : printf("g");
return 0;
}
我原本期望的输出是"g",但实际上却是"s"。这里进行了什么样的转换?
我正在尝试将无符号整数与有符号字符进行比较,就像这样:
int main(){
unsigned int x = 9;
signed char y = -1;
x < y ? printf("s") : printf("g");
return 0;
}
第6.3.1.8节:“通常算术转换”细节介绍了隐式整数转换。
如果两个操作数具有相同的类型,则不需要进行进一步转换。
这不适用于本例,因为它们是不同的类型。
否则,如果两个操作数都具有带符号整数类型或者两者都具有无符号整数类型,则具有较小整数转换等级的操作数将转换为具有更高等级的操作数的类型。
这不适用于本例,因为一个是有符号的,另一个是无符号的。
否则,如果具有无符号整数类型的操作数的等级大于或等于另一个操作数的类型的等级,则具有带符号整数类型的操作数将转换为具有无符号整数类型的操作数的类型。
Bingo。 x
等级比 y
高,因此将 y 提升为 unsigned int
。这意味着它从 -1
变成了 UINT_MAX
,远大于9。
其余规则不适用于本例,但我会出于完整性而包含它们:
否则,如果具有带符号整数类型的操作数的类型可以表示无符号整数类型的所有值,则具有无符号整数类型的操作数将转换为具有带符号整数类型的操作数的类型。
否则,两个操作数都将转换为与具有带符号整数类型的操作数的类型相对应的无符号整数类型。
本问题相关的等级如下所示。 所有等级均在C99第6.3.1.1节“布尔值、字符和整数”中详细说明,因此您可以参考该部分以获取更多详细信息。
long long int
的等级应大于long int
的等级,
long long int
的等级应该大于int
,int
的等级应该大于short int
,short int
的等级应该大于signed char
。
char
的等级应该与signed char
和unsigned char
的等级相同。
(signed int)x < (signed int)y
将保证您最初期望的结果。 - Leeint
无法容纳足够大的值,我会切换到long
,甚至是long long
(需要时)。太多次了,我被拒绝变为负数的无符号整数咬伤,使我的许多循环成为无限循环,导致痛苦和大量的抱怨 :-) - paxdiablosize_t
,它是无符号的。大多数情况下,这种类型完全捕捉了我从整数类型所需的语义。对于人们正在处理的任务,int
几乎总是错误的类型。对我而言有意义的带符号类型是 ptrdiff_t
,但仅此而已。 - Jens Gustedtint
类型。 - Steve Jessop运行以下代码:
int main(){
unsigned int x = 9;
signed char y = -1;
printf("%u\n", (unsigned int)y);
x < (unsigned int)y ? printf("s") : printf("g");
return 0;
}
4294967295 s经过强制类型转换后,y的值变得非常大。这就是为什么输出结果为s的原因。
y
被提升为unsigned int
,变成了一个非常大的值(由于溢出)。因此条件得到满足。字符被提升为无符号整数,其值为MAX_UINT,大于9。
sizeof(int)== sizeof(char)
,它们都将提升为“int”。 在这种情况下,两者都将成为“unsigned int”。因此,如果sizeof(int)> sizeof(char)
,则(unsigned char) 9 <(signed char) -1
大致上是错误的,如果sizeof(int)== sizeof(char)
则为真。 我说“大致”是因为重要的是范围而不是大小,但是假设int
中没有填充位,它们对应。这很愚蠢,但通常在完全可移植的代码中不要使用小于“int”的类型进行算术运算(包括比较)。 - Steve Jessop
y
的值是多少? - Cody Gray