【问题标题】:unexpected behavior of unsigned variables when assigned negative values分配负值时无符号变量的意外行为
【发布时间】:2013-11-14 16:11:25
【问题描述】:

这是一个代码sn-p:

unsigned short a=-1;
unsigned char b=-1;
char c=-1;
unsigned int x=-1;
printf("%d %d %d %d",a,b,c,x);

为什么输出是这样的:

65535 255 -1 -1

?

有人可以分析一下吗?

【问题讨论】:

  • 你期望的输出是什么?
  • 你的编译器应该警告你%d%d 需要 int 类型,但并非所有参数都是 int 类型。因此,编译器将在打印之前执行隐式转换为 int
  • c=255 或 x=very large no,但不是两者都 -1 -1
  • @user2976610 printf with %d as format 转换为 int。一个 int 已签名。因此 c 为 -1,x 为 -1。检查大流士的答案
  • 如果是这样,那么 a 和 b 也可能被转换为 int..right

标签: c printf output unsigned signed


【解决方案1】:

您正在使用%d 打印值,该值用于有符号数字。该值被“转换”为有符号数(实际上按位保持不变,但第一位的解释不同)。

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

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

无论如何,%u 用于无符号数字。

它是如何工作的?

位值 255 是11111111。如果将其视为无符号数,它将是 255。如果将其视为有符号数 - 它将是 -1(第一位通常确定符号)。 当您在 printf 中将值传递给 %d 时,该值将转换为 32 位整数,如下所示:00000000000000000000000011111111。由于第一位是 0,因此该值仅打印为 255。它对您的 short 的工作方式类似。

32 位整数的情况有所不同。它立即被分配了一个11111111111111111111111111111111 值,它代表单数符号中的-1。由于您在 printf 中使用了%d,因此它被解释为-1

【讨论】:

  • 我要详细解释plzz
  • 如果你使用了%lld,你还需要转换为long long,否则你会得到未定义的行为。
  • @user2976610 扩展了答案
  • @interjay thx,添加了信息;它不会是 C 中未指定的行为,而不是未定义的行为吗?
【解决方案2】:

基本上,您不应将负值分配给“无符号”变量。你试图在编译器上玩花样,谁知道它会做什么。现在,“char n = -1;”没关系,因为“n”可以合法地采用负值,并且编译器知道如何处理它。

【讨论】:

  • 你不能在编译器上耍花招!将 -1 分配给无符号变量只是将可能的最大值分配给变量的另一种方法。 -1 --> 0xffff --> (无符号)65535=(2^16)-1
猜你喜欢
  • 2021-11-13
  • 1970-01-01
  • 2014-08-02
  • 2017-01-29
  • 2019-11-06
相关资源
最近更新 更多