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。@注意:我知道这一点,但我还是要感谢您(因为我没有意识到这一点,您会为我节省很多工作)