我不希望打印的值是初始的负值。我是否因为类型转换而缺少某些内容?
#include<stdint.h>
int main() {
int32_t color = -2451337;
uint32_t color2 = (uint32_t)color;
printf("%d", (uint32_t)color2);
return 0;
}
答案 0 :(得分:3)
你拿了一堆比特(存储在有符号值中)。然后,您告诉CPU将该堆位解释为无符号。然后你告诉cpu再次渲染相同的一串位(%d)。因此,您会看到与第一次输入相同的内容。
C只处理一堆比特。如果您选择的值接近所涉及类型的代表性限制(阅读二进制补码表示),那么我们可能会看到一些时髦的效果,但您选择的值并非如此。所以你收回了你的内容。
答案 1 :(得分:3)
int32_t color = -2451337;
uint32_t color2 = (uint32_t)color;
演员阵容是不必要的;如果省略它,则会隐式完成相同的转换。
对于两种数字类型之间的任何转换,如果该值在两种类型中均可表示,则转换将保留该值。但由于color
是否定的,所以情况并非如此。
对于从有符号整数类型到无符号整数类型的转换,结果是实现定义(或者它可以引发实现定义的信号,但我不知道任何编译器那样做。)
在大多数编译器下,相同大小的整数类型之间的转换只会复制或重新解释构成表示的位。该标准要求int32_t
使用二进制补码表示,因此如果转换只是复制位,则结果将为4292515959
。
(C标准允许其他结果,但不太可能由现实编译器实现。该标准允许有符号整数类型的补码和符号和幅度表示,但特别需要int32_t
使用二进制补码;一个补码CPU的C编译器可能只是不能定义int32_t
。)
printf("%d", (uint32_t)color2);
同样,演员表是不必要的,因为color2
已经是uint32_t
类型。但是"%d"
格式需要类型为int
的参数,这是一个带符号的类型(可能窄到16位)。在这种情况下,uint32_t
值不会转换到int
。很可能color2
的表示将被视为,好像它是一个int
对象,但是行为是未定义的,所以就C标准而言,它实际上只涉及任何事物。可能会发生。
要打印uint32_t
值,您可以使用PRId32
中定义的<inttypes.h>
宏:
printf("%" PRId32, color32);
或者,或许更简单地说,您可以将其转换为最宽的无符号整数类型并使用"%ju"
:
printf("%ju", (uintmax_t)color32);
这将打印4292515959
的实现定义值(可能是color32
)。
您应该在格式字符串中添加换行符\n
。
更多狡辩:
您错过了#include <stdio.h>
,如果您致电printf
,则需要{。}}。
int main()
没问题,但首选int main(void)
。