为什么用%d打印字符变量在c中给出负值?

Kiblekat

我尝试了以下代码,期望输出为正64:

char val = 0x80; 
printf("%d",val>>1);

我对发生的事情的理解是(如果我错了,请纠正我):

  1. 参照ASCII表,没有0x80到任何字符的映射,因此我认为这是作为无符号整数存储的。
  2. 这按位格式表示为1000 0000,因此向右移位1将导致0100 0000
  3. 当打印为整数值时,它将显示为正64。

但是显示-64。

相反:

char val = 0x40; 
printf("%d",val>>1);

给出正32。

在第一种情况下而不是在第二种情况下,该值是否隐式转换为带符号整数?

埃里克·波斯蒂奇(Eric Postpischil)

您的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>>1val自动从提升charint,具有相同的值,-128,然而,与32位int,它随后将被表示为11111111111111111111111110000000代替10000000然后右移“算术”,其传播符号位,得出的结果为11111111111111111111111111111000000,某些C实现可能“逻辑上”右移,将符号位设置为零,得出01111111111111111111111111111000000,在这种情况下,printf将显示“ 2147483584”,即2 31 -64)。

ASCII是否具有代码为0x80的任何字符均无关紧要。无论使用哪种字符编码方案,C规则均适用于所涉及的值。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章