分配负值时无符号变量的意外行为

Vis*_*ath 1 c printf unsigned signed output

这是一段代码:

unsigned short a=-1;
unsigned char b=-1;
char c=-1;
unsigned int x=-1;
printf("%d %d %d %d",a,b,c,x);
Run Code Online (Sandbox Code Playgroud)

为什么输出是这样的:

65535 255 -1 -1
Run Code Online (Sandbox Code Playgroud)

有人可以分析一下吗?

Dar*_*usz 6

您正在打印%d用于签名号码的值.该值被"转换"为有符号数(它实际上按位保持相同,但第一位的解释不同).

对于unsigned char和short - 它们也被转换为32位int,因此值适合它.

如果您使用%lld(并将值转换为long long,否则可能是未指定的行为),即使最后两个数字可能会打印为无符号.

总之,使用%u无符号数.

它是如何工作的?

位值为255 11111111.如果将其视为无符号数,则为255.如果将其视为有符号数 - 它将为-1(第一位通常确定符号).将值传递给%dprintf时,该值将转换为32位整数,如下所示:00000000000000000000000011111111.由于第一位为0,因此该值仅打印为255.它类似于您的short.

32位整数的情况不同.它立即被赋予一个11111111111111111111111111111111值,在singed表示法中代表-1.因为你已经%d在你的printf中使用了它,它被解释为-1.