我尝试了以下代码,期望输出为正64:
char val = 0x80;
printf("%d",val>>1);
我对发生的事情的理解是(如果我错了,请纠正我):
但是显示-64。
相反:
char val = 0x40;
printf("%d",val>>1);
给出正32。
在第一种情况下而不是在第二种情况下,该值是否隐式转换为带符号整数?
您的C实现使用一个八位符号char
。(C标准允许带char
符号的或无符号的。)在中char val = 0x80;
,achar
不能代表您用其初始化的值128。在这种情况下,值128会转换为该值char
,根据C 2018 6.3.1.3 3,它会产生一个实现。定义的值或陷阱。您的实现可能产生−128。(这是常见的结果,因为二进制的128为10000000,并且将超出范围的结果转换为八位二进制补码整数通常会将值的低八位重新解释为八位二进制补码。在二进制补码中,则10000000代表−128。)
因此val>>1
要求将-128右移一位。根据C 2018 6.5.7 5,向右移动负值会产生实现定义的值。产生-64是常见的结果。
(详细地,在val>>1
,val
自动从提升char
到int
,具有相同的值,-128,然而,与32位int
,它随后将被表示为11111111111111111111111110000000代替10000000然后右移“算术”,其传播符号位,得出的结果为11111111111111111111111111111000000,某些C实现可能“逻辑上”右移,将符号位设置为零,得出01111111111111111111111111111000000,在这种情况下,printf
将显示“ 2147483584”,即2 31 -64)。
ASCII是否具有代码为0x80的任何字符均无关紧要。无论使用哪种字符编码方案,C规则均适用于所涉及的值。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句