【问题标题】:unsigned integers in C [closed]C中的无符号整数[关闭]
【发布时间】:2013-02-26 17:42:04
【问题描述】:

当我在下面运行程序时,它会输出 109876543210-1-2-3-4-5-6-78-9-10-11-12-和 s0 等。为什么这样?无符号整数是什么概念?

 main ()
   {
      unsigned int i;
       for (i = 10; i >= 0; i--)
                 printf ("%d", i);
   }

【问题讨论】:

  • 顺便说一句,c 中带符号的 int 和无符号的 int 之间的区别例如在于它进行位移的方式,这实际上意味着它使用的是 sal/sar 还是 shl/shr 指令。否则寄存器中的数字看起来相同。
  • @stupid_idiot,它还影响比较、乘法 (mul/imul)、除法 (div/idiv) 和传播到更大的类型。也许还有别的,不太确定。
  • 这个问题没有任何问题,因此不应将其作为“不是一个真正的问题”来关闭。但由于非常基本的性质,也许它“过于本地化”。

标签: c unsigned-integer


【解决方案1】:

无符号整数总是非负的,即大于或等于 0。当您在无符号整数类型中从 0 中减去 1 时,您最终会得到 MAX_INT。

因此,您的 for 循环将永远不会终止。

但是,如果您希望 printf 打印无符号值而不是有符号值,则需要在 printf 中使用“%u”而不是“%d”。

【讨论】:

  • 我认为你的意思是非负数。 0U 绝对不是正面的。 :-)
  • @R.. 确实如此。我会编辑,呃 :-)
【解决方案2】:

%d 格式字符串将替换值视为int,这是有符号的。

【讨论】:

    【解决方案3】:

    为什么会这样?

    因为你的程序有一个未定义的行为(使用%d 来打印int 来打印unsigned) - 所以你可以期待任何事情发生。

    为什么是无限循环?因为unsigned int 始终是>= 0

    无符号整数是什么概念?

    这是一个... 无符号整数。一个非负的整数。

    【讨论】:

    • @Virgile 在语句printf("%d", u); 中没有从unsignedint 的转换,正如在语句printf("%d", f); 中从floatint 的转换一样。 6.3.1.3 不适用,7.19.6.1:8 表示%d 对应的参数应该是int
    • 对于正常的函数调用,会发生转换,但你是对的,可变参数函数的行为不同,7.19.6.1§9 明确表示这是 UB。因此,我将删除原始评论。
    【解决方案4】:

    您使用%d,因此 printf 将值解释为带符号的。 与无符号数为零 (>=0) 的比较始终为真。

    因此,虽然值从 10 到 0,但输出正常 (109876543210)。之后,该值变为巨大的正数(最大值,对于 32 位 int,它是 0xFFFFFFFF)。与 0 的比较为真,因此循环继续。但是在printf 0xFFFFFFFF 中产生-1,因为使用了%d。然后循环继续到0xFFFFFFFE,即-2,但仍是>= 0,未签名。

    使用%u

    【讨论】:

    • 是的,这是程序并在 linux 上运行 #include int main() { unsigned int i; for (i = 10; i >= 0; i--) printf ("%d", i);返回0; }
    【解决方案5】:

    printf 不知道你给它的变量的类型,它得到的只是值(位本身)。您必须告诉它如何解释该值,并使用%d 告诉它将其解释为有符号整数。

    【讨论】:

      【解决方案6】:

      您正在使用带有 printf() 的“%d”,它是有符号整数的格式说明符。

      【讨论】:

        【解决方案7】:

        声明unsigned integer 指示编译器对变量使用无符号操作。例如,>> 运算符对无符号整数和有符号整数有不同的行为(具体来说,它是否应该保留符号位)。

        要打印无符号整数,应使用%u 格式。

        【讨论】:

        • 在 10987654321042949672954294967294429496729342949672924294967291429496729 等输出中使用 '%u' 时...这是什么意思。我只尝试打印 10 到 0 个无符号数字
        • 由于您的打印件之间没有分隔符,因此您实际看到的是数字 - 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 4967295, 4294967294,4294967293... 第 11 个数字之后(包括第 11 个数字)之后的数字是由于您的退出条件没有被填充(无符号整数总是 >=0,所以当您从 0 减少它们时它们会翻转 - 您可以阅读它@987654321 @)
        【解决方案8】:

        有符号整数(我们将使用 16 位)范围从 -32768 到 32767(0x8000 到 0x7FFF),而 无符号 整数范围从 0 到 65535(0x0000 到 0xFFFF)。所以无符号整数不能有负值,这就是你的循环永远不会终止的原因。但是,您已经告诉打印程序格式化输出就好像它是签名 (%d) 以便您在输出中看到格式化为负值的数字。在某种程度上,计算机中的所有内容都只是需要解释的一串位,您的代码示例使用相同位模式的两种不同解释......您的无符号整数。

        【讨论】:

        • 不要对unsignedint的位宽做假设。
        • 我没有假设,这就是为什么我说“我们将使用 16 位”作为 示例
        【解决方案9】:

        您应该在 printf 中使用%u 作为format specifier,否则该值将被强制转换为int

        【讨论】:

        • @sixlettervariables 哈哈对不起我的意思是%u
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-08-18
        • 2015-01-24
        • 1970-01-01
        • 1970-01-01
        • 2023-03-17
        相关资源
        最近更新 更多