C 如果语句比较,unsigned变为signed-in?
我在这个网站上搜索了一个答案,找到了很多关于无符号/有符号比较的回复,但问题是只有无符号参数被比较,但仍然很有趣 以下代码的问题在于,第一个C 如果语句比较,unsigned变为signed-in?,c,comparison,if-statement,unsigned,C,Comparison,If Statement,Unsigned,我在这个网站上搜索了一个答案,找到了很多关于无符号/有符号比较的回复,但问题是只有无符号参数被比较,但仍然很有趣 以下代码的问题在于,第一个if-station没有像第二个(“world”)那样发生(“hello”)。我将其解释为在中进行的计算,如果-station生成一个负数,但与保存到变量中的结果完全相同的计算不会产生负数(即使结果保存到有符号变量中) 使用的编译器是GCC4.4 unsigned short u16_varHigh; unsigned short u16_varLow;
if
-station没有像第二个(“world”)那样发生(“hello”)。我将其解释为在中进行的计算,如果-station生成一个负数,但与保存到变量中的结果完全相同的计算不会产生负数(即使结果保存到有符号变量中)
使用的编译器是GCC4.4
unsigned short u16_varHigh;
unsigned short u16_varLow;
unsigned short u16_Res1;
signed short s16_Res1;
u16_varHigh = 0xFFFF;
u16_varLow = 10;
u16_Res1 = u16_varLow - u16_varHigh; // response is 11 as expected
s16_Res1 = u16_varLow - u16_varHigh; // response is 11 as expected
// Does not enter
if( (u16_varLow - u16_varHigh) > (unsigned short)5 )
{
printf( "hello" );
}
// Does enter
if( (unsigned short)(u16_varLow - u16_varHigh) > 5 )
{
printf( "world" );
}
有谁能给我解释一下,也许能想出一个解决方案,使第一个if
-语句也能工作吗?表达式中:
if( (u16_varLow - u16_varHigh) > (unsigned short)5 )
(u16\u varLow-u16\u varHigh)
将升级为int
,并评估为-65525。解决问题的方法是强制转换为无符号类型,就像您在“Does enter”-代码中所做的那样
原因s16\u Res1=u16\u varLow-u16\u varHigh代码>产生11是因为减法的结果,-65525不适合短字符。第一个,如果((u16_varLow-u16_varHigh)>(unsigned short)5)
将永远不会通过,因为(u16_varLow-u16_varHigh)
返回负数,因为它被视为整数。第二个是相同的负数,短到无符号,这就是它通过的原因
注意-您知道所有这些都依赖于平台,对吗?short
,int
等的大小取决于具体的平台。在其他答案中,我们已经看到
u16_varLow - u16_varHigh
对于您(使用16位short
和32位int
)相当于
(int)u16_varLow - (int)u16_varHigh
s16_Res1 = -65525;
因此,它的结果是int
值-65525
。因此,任务
s16_Res1 = u16_varLow - u16_varHigh;
相当于
(int)u16_varLow - (int)u16_varHigh
s16_Res1 = -65525;
在16位short
的情况下,会产生“未定义的行为”。不幸的是,编译器决定分配11
。(不幸的是,我认为最好早点失败。)
相比之下
u16_Res1 = -65525;
是一个有效的赋值,因为u16_Res1
是无符号类型,且无符号类型的算术是二的适当幂的模。在“常用算术转换”中,小于int
的类型在大多数表达式中使用之前会升级为int
或无符号int
。规则是,如果int
可以表示较小类型的所有值,则将其提升为int
;否则它将升级为无符号int
。这通常被认为是一个缺点,因为在许多情况下,它会导致无符号字符
和无符号短字符
值提升为int
这正是您所看到的-u16\u varLow
和u16\u varHigh
和(无符号短)5
在减法和比较之前都被提升为int
,然后使用int
进行比较。如果希望确定表达式将使用无符号算术,则必须在无符号int
中执行,而不是在无符号short
中执行:
if( ((unsigned)u16_varLow - (unsigned)u16_varHigh) > 5U )
可能重复我不同意。关于类似的主题,但不是重复的。实际上,在减法之前,u16\u varLow
和u16\u varHigh
分别提升为int
。是否完成了两个单独的强制转换?将不输入以下if语句:u16_varHigh=0xff00
如果(u16_varHigh<-5)。。。决定签字是因为删减。因此,比较一个无符号(具有高位集)将被视为无符号,但比较2个无符号与它被视为有符号之间的差异。不知怎的,它感觉有点不对……还值得注意的是,(unsigned short)
没有任何效果(在32位机器上)<如果unsigned short
的所有值都适合int
,则code>(unsigned short)5在被视为比较输入之前将提升为int
。如果在short和int宽度相同的处理器上执行此操作,(unsigned short)5
将升级为unsigned
,lhs也是如此,条件将为真。@Wilmer我不太明白您的意思,但我认为您误解了。示例中的“两个无符号之间的差”实际上是两个整数之间的差,因为在考虑减法之前,u16都转换为整数。如果您改为(unsigned)u16\u varLow-(unsigned)u16\u varHigh
,则减法的结果将是unsigned。@注意:我知道这一点,但我还是要感谢您(因为我没有意识到这一点,您会为我节省很多工作)