int *int_pointer = malloc(10);
*int_pointer = 53200;
printf("The integer at byte #0 is set to: %d \n", (char) *int_pointer);
结果:-48
所以我只是试着看看会发生什么,我得到了这个意想不到的结果。
为什么-48?怎么会变成负面的呢?
答案 0 :(得分:8)
我认为C99 / C11标准中的正确参考是§6.3.1.3
(强调我的):
- 当整数类型的值转换为_Bool以外的另一个整数类型时,如果该值可以由新的 类型,它没有变化。
- 否则,如果新类型为无符号,则该值将由重复添加或减去一个以上的值转换为 可以用新类型表示,直到值在范围内 新型。
- 否则,新类型已签名且其中的值无法表示;要么结果是实现定义,要么引发实现定义的信号。
醇>
请注意,char
类型存在问题,因为如果它实际上表示为有符号或无符号,它也是实现定义的。标准本身完全定义的唯一方法是强制转换为unsigned char
类型。
假设对于您的实现sizeof(int) == 4
并且它使用二进制补码方法来存储有符号整数,则数字53200
表示为:
0000 0000 0000 0000 1100 1111 1101 0000
请注意,如果你有小端CPU(可能是真正的假设),那么字节顺序,或者更严格的是它们实际存储在内存和CPU寄存器中的方式是反转的,即。该号码存储为:
0000 1101 1111 1100 0000 0000 0000 0000
(unsigned char) 53200
产生的是(纯数学意义上)减法的结果(注意标准保证sizeof(unsigned char) == 1
):
53200 - 256 - 256 - ... - 256 = 53200 % 256 = 208
是二进制1101 0000
可以在数学上证明结果始终与“截止”相同,仅作为演员的结果,仅保留最后,最不重要的字节。
printf()
注意:正如@pmg printf()
指出的那样是可变函数,并且由于默认参数提升,它的可选参数类型为unsigned char
(或signed char
和{{1 (以及)始终提升为char
,但这次它只是“一种形式”。
作为替代解决方案,您可以使用biwise int
和运算符使用适当的掩码来获取特定数字的最低有效字节,例如:
&
答案 1 :(得分:5)
将数据类型转换为另一种不足以容纳所有可能值的数据类型是未定义的行为。对于未定义的行为,编译器可以随心所欲地执行任何操作,因此通常它会为实现者执行最少的工作,因为它们是自动正确的并且您总是错误的。
因此,你不会问“为什么会这样?” - 你应该很高兴你没有得到52301,或42,或“帮助!我被困在整数库中!”代替。
答案 2 :(得分:2)
这很简单:53200 = 0xCFD0
和0xCF
= 207,signed char
= -48 ...
答案 3 :(得分:1)
我认为@fritzone是正确的。
由于C中整数的范围是-32768 to 32767
,因此在32767之后它将变为-32768而不是32768,因此它在53200处打印-48。
尝试使用值53201,它将打印出值-47,依此类推..