负数分配给一个unsigned int?

在C编程语言中, unsigned int只用于存储正值。 但是,当我运行下面的代码:

 unsigned int x = -12; printf("%d", x); 

输出仍然是-12。 我以为应该打印出来12,还是我误解了一些东西?

等号右边的-12被设置为一个有符号的整数(可能是32位),并且将有hex值0xFFFFFFF4 。 编译器生成代码将这个有符号的整数移动到你的无符号整数x ,这个整数也是一个32位实体。 编译器假定你只对等号右边有一个正值,所以它只是把所有的32位移到x 。 现在x的值为0xFFFFFFF4 ,如果解释为正数,则为4294967284 。 但%dprintf格式说32位被解释为一个有符号的整数,所以你得到-12 。 如果您使用了%u ,它将打印为4294967284

无论哪种情况,你都没有得到你所期望的,因为C语言“信任”代码的作者只是要求“明智”的东西。 这在C中是很常见的。如果你想给x赋一个值,但不确定等号右边的值是否为正数,你可以写成unsigned int x = abs(-12); 并强制编译器生成代码,以将有符号整数的绝对值移到无符号整数。

int是unsinged的,但是你已经告诉printf将它看作一个带符号的int。

尝试

 unsigned int x = -12; printf("%u", x); 

它不会打印“12”,但会打印无符号整数减去11的最大值。

运动给读者是要找出为什么:)

将%d传递给printf会告诉printf把参数当作一个有符号的整数,而不pipe你实际传递的是什么。 使用%u作为无符号打印。

这一切都与价值的解释有关。

如果你假设16位有符号和无符号整数,那么这里有一些不完全正确的例子,但是展示了这个概念。

0000 0000 0000 1100无符号整数,有符号整数值12

1000 0000 0000 1100有符号整型值-12,和一个大的无符号整数。

对于有符号整数,左边的位是符号位。 0 =正面1 =负面

对于无符号整数,没有符号位。 左边的位,让你存储一个更大的数字。

所以你没有看到你期望的是这个原因。

unsigned int x = -12,以-12为整数,并将其存储到x中。 x是无符号的,所以什么是符号位,现在是一个值。

printf让你告诉编译器你想如何显示一个值。

%d表示将其显示为有符号整数。 %u表示将它显示为无符号整型。

C让你做这种东西。 程序员在掌控之中

有点像枪支。 这是一个工具。 您可以正确使用它来处理某些情况,或不正确地删除您的一个脚趾。

一个可能有用的情况是以下

unsigned int allBitsOn = -1;

该特定值将所有位设置为1

1111 1111 1111 1111

有时可能有用。

 printf('%d', x); 

意味着打印一个有符号的整数。 你将不得不写这个:

 printf('%u', x); 

此外,它仍然不会打印“12”,这将是“4294967284”。

他们确实存储正面价值。 但是你输出(非常高)正值作为一个有符号的整数,所以它会被重新解释(以实现定义的方式,我可能会添加)。

使用格式标志"%u代替。

你的程序有未定义的行为,因为你把错误的types传递给了printf (你告诉它你要传递一个int但是你传递了一个unsigned int )。 考虑一下你自己的幸运,即实现所做的“最简单”的事情只是默默地打印错误的值,而不是跳转到一些有害的代码。

你所缺less的是printf(“%d”,x)期望x被签名,所以尽pipe你给-x指定了-12,它将被解释为2的补码,这将是一个非常大的数字。 但是,如果将这个非常大的数字传递给printf,则会将其解释为signed,从而将其正确转换回-12。

在打印f中打印无符号的正确语法是“%u” – 试试看看它做了什么!

将一个负值分配给一个无符号整数不会计算出负数的绝对值:它将解释为一个无符号整数,即负值的二进制表示forms,即4294967284(2 ^ 32 – 12)。

printf(“%d”)执行相反的解释。 这就是为什么你的程序显示-12。

当你试图显示int值时,你将它传递给一个(int)参数而不是一个(unsigned int)参数,并且导致它打印-12而不是(4294967284)。 整数以hex格式存储 ,-12为int与hex格式的无符号整数4294967284相同。这就是为什么“%u”打印所需的正确值而不是“%d”..这取决于您的参数types。良好的运气!

当编译器将-12隐式转换为无符号整数时,底层二进制表示保持不变。 这种转换纯粹是语义的。 二进制补码整数的符号位成为无符号整数的最高有效位。 因此,当printf将无符号整数视为带有%d的有符号整数时,它将看到-12。

在一般情况下,只有正数可以被存储,负数不被明确地存储,但是它们的二进制补码被存储。 在这里用相同的方式,-12的二进制补码将被存储在“x”中,并使用%u来获得它。

int和unsigned int用于分配一些字节来存储一个值。

编译器应该给出关于有符号不匹配的警告,但它确实不会影响内存中代表值-12的位。

%x,%d,%u等告诉编译器在打印时如何中断许多位。