unsigned和int-gotcha
可能重复:unsigned和int-gotcha,c,types,type-conversion,C,Types,Type Conversion,可能重复: 输出:a>b int b=2; int a=-2; if(a>b) printf("a>b"); else printf("b>a"); 输出:b>a 请有人解释一下输出在第一种情况下,两个操作数都转换为无符号整数,转换后的a将是UINT\u MAX-1,这比b大得多,因此输出 除非您理解算术转换的语义,否则不要比较有符号整数和无符号整数,结果可能会让您感到惊讶 以下内容摘自C编程语言的Kernighan和Ritchie-2.7类型转换-第44
输出:a>b
int b=2;
int a=-2;
if(a>b)
printf("a>b");
else
printf("b>a");
输出:b>a
请有人解释一下输出在第一种情况下,两个操作数都转换为无符号整数,转换后的
a
将是UINT\u MAX-1
,这比b
大得多,因此输出
除非您理解算术转换的语义,否则不要比较有符号整数和无符号整数,结果可能会让您感到惊讶 以下内容摘自C编程语言
的Kernighan
和Ritchie
-2.7类型转换
-第44页;本页的后半部分详细解释了相同的场景。下面有一小部分供您参考
当涉及无符号
操作数时,转换规则很复杂。问题是有符号值和无符号值之间的比较依赖于机器,因为它们取决于各种整数类型的大小。例如,假设int
的长度为16位,long
的长度为32位。然后,-1L<1U
,因为1U
,它是一个int
,被提升为一个带符号的long
。但是-1L>1UL
,因为-1L
被提升为无符号long
,因此看起来是一个更大的正数。在第一种情况下,将无符号a转换为有符号int。然后比较这两个值
有符号和无符号类型之间的类型转换列组在C99中可以具有相同的列组。这是当一个无符号类型和一个有符号类型具有相应的类型时,当发生这种情况时,结果由编译器决定
比较有符号值和无符号值时,如果无符号值不能全部用有符号类型表示,则有符号操作数将升级为无符号操作数。这是通过一个相当于重新解释2-s补码位模式的公式完成的
负数有很多高位
由于您的操作数都是相同的秩,所以只需比较无符号位模式即可
因此-2用111111..110表示,比可能的最大值小一个,当解释为无符号时,它很容易超过2。您需要学习C中运算符的操作以及C升级和转换规则。它们在C标准中进行了解释。其中的一些摘录以及我的评论:
6.5.8关系运算符
语法
1关系表达式:
移位表达式
关系表达式<移位表达式
关系表达式>移位表达式
关系表达式=移位表达式
语义
3如果两个操作数都具有算术类型,则通常的算术转换为
已执行。
大多数运算符在实际操作(加法、乘法、比较等)之前都包含此“常用算术转换”步骤。-Alex
6.3.1.8常用算术转换
1许多期望算术类型的操作数的运算符会导致转换并产生结果
以类似的方式输入。目的是确定操作数的通用实数类型
结果呢。对于指定的操作数,将转换每个操作数,而不更改类型
域,指向其对应实类型为公共实类型的类型。除非
否则,公共实数类型也是
结果,其类型域是操作数的类型域(如果操作数相同),
否则会很复杂。这种模式称为通常的算术转换:
- 首先,如果其中一个操作数的对应实数类型为长双精度,则另一个操作数
操作数在不更改域类型的情况下转换为
对应的实数类型为长双精度
- 否则,如果任一操作数的对应实数类型为双精度,则另一个操作数
操作数在不更改域类型的情况下转换为
对应的实数类型是double
- 否则,如果其中一个操作数的对应实数类型为float,则另一个操作数
操作数在不更改域类型的情况下转换为
相应的实数类型是float
- 否则,将对两个操作数执行整数提升。然后
以下规则应用于提升的操作数:
- 如果两个操作数的类型相同,则无需进一步转换
- 否则,如果两个操作数都具有有符号整数类型或都具有无符号整数类型
整数类型,则类型为较小整数转换秩的操作数为
已转换为具有更高秩的操作数类型
- 否则,如果具有无符号整数类型的操作数的秩大于或等于
等于另一个操作数类型的秩,然后为
有符号整数类型转换为无符号的操作数类型
整数类型
- 否则,如果带符号整数类型的操作数的类型可以表示
具有无符号整数类型的操作数类型的所有值,然后
无符号整数类型的操作数转换为
带符号整数类型的操作数
- 否则,两个操作数都将转换为无符号整数类型
对应于带符号整数类型的操作数的类型
6.3.1.3有符号和无符号整数
当整数类型的值转换为除_Bool以外的其他整数类型时,如果该值可以用新类型表示,则该值不变
否则,如果新类型是无符号的,则通过重复添加或
比新类型中可以表示的最大值多减去一个
直到值在
int b=2;
int a=-2;
if(a>b)
printf("a>b");
else
printf("b>a");