简单的C程序输出不是预期的

我正在做这个简单的程序,我的思绪陷入困境

#include int main() { signed int a; signed char c; unsigned char b; b = 0xf4; a = (signed)b; // 1)this assignment should be same c = (signed)b; printf("%d\n",a); a = c; // 2)as this one printf("%d \n",a); return 0; } a = 244, a = -12 

我试图确保分配尽可能顺利,但我得到两个不同的答案,我希望两者都是-12。 我错过了什么小事?


相关的问题是

 { b = 0xf4; c = 0xf4; a = (signed int)b; //trying to save sign but get 244 printf("%d\n", a); a = c; //sign saved here and got -3 printf("%d", a); } 

244,-3

所以我试图从unsigned char中保存标志。 这有可能吗?

  signed char c; unsigned char b; b = 0xf4; /* ... */ c = (signed)b; 

b值为0xf4244 ),但c类型( signed char )只能保存-128127之间的值(在您的实现中)。 因此,当244被分配给c它首先被转换为signed char ,C表示这个整数转换是实现定义的。 gcc因为大多数实现只包含模数256 ,这就是为什么c的值是-12

这是gcc文档:

http://gcc.gnu.org/onlinedocs/gcc/Integers-implementation.html

“为了转换为宽度为N的类型,将值减去模2 ^ N,使其在类型范围内”

问题位于:

 c = (signed)b; 

将b,244的值转换为带符号的char会导致整数溢出,从而产生-12值。 将c的类型更改为signed int可以解决问题。

据我了解, 244的输出是正确的。 首先,将b初始化为值244表示为hex文字,然后将其转换为带signed int a ,其可以保持值244 。 根据printf格式字符串的规范, 244的输出是预期的。

事件,如果您没有通过签名对’b’进行类型转换,您将获得相同的结果。

在第一次任务中

a =(签名)b;

你正在加载一个带有0xf4的有符号整数(16位/ 32位/ 64位)它可以容纳,并且当msb为’0’时,结果将是244。

如果你的int长8位,那么结果将是’-12’。

在第二种情况下,你必须得到’-12’,因为’-12’的2的补码是0xf4。