【问题标题】:Behavior of unsigned int in CC 中 unsigned int 的行为
【发布时间】:2015-01-19 06:45:21
【问题描述】:

unsigned int 在 C 中的大小是 0 to 65,535 or 0 to 4,294,967,295

我在 C 中使用以下代码进行了测试:

unsigned int number = 0;
number -= 300;
printf("%d\n", number);

输出:-300

我记得如果 unsigned int 变量的值低于 0,它应该回绕,我希望输出类似于 4294966996。但是从控制台打印的输出是-300

我在 C++ 中测试了类似的语句,它确实给了我4294966996

我的问题是:为什么输出是-300,尽管它是unsigned int


PS:我浏览了几篇标题相似的帖子,但它们并没有解决相同的问题:

signed vs unsigned int in C

Unexpected results on difference of unsigned ints

【问题讨论】:

  • printf 是一个哑函数。您必须确保将其传递给它期望的类型!
  • 请记住,使用有符号整数格式字符串打印无符号整数是未定义的行为。
  • 最后一个问题:我是否正确地说,如果我用 %d 打印它,它会在打印前将其隐式转换为已签名?
  • 我认为对于如何实现 printf 没有要求,它可能只是用 char* 为您的参数别名,并将字节解析为适当的 c 字符串(基于您的格式字符串)

标签: c int unsigned


【解决方案1】:

因为printf("%d\n", number); 将打印一个有符号值,即使参数是无符号的。使用printf("%u\n", number); 正确打印无符号值。

【讨论】:

    【解决方案2】:

    @UniCell 出色答案的一些背景知识。

    硬件以完全相同的方式存储intunsigned int。没有不同。如果你开始对它们进行加法或减法,它们将以完全相同的方式上溢和下溢。

    0xFFFFFFFF + 1 = 0
    0 - 1 = 0xFFFFFFFF
    

    如果我们认为结果是无符号的,0xFFFFFFFF 表示 4,294,967,295,否则表示 -1。它被称为 2 的补码存储。加法和减法是符号不可知的。但是乘法和除法不是,因此通常有不同的有符号和无符号机器指令。

    这些变量的类型只有编译器知道,运行时不知道。 printf 的参数可以是任意类型,传递的变量在运行时不携带类型信息。所以你必须在格式字符串中告诉printf如何解释它们。

    【讨论】:

    • 无法保证,但在实践中,总是如此。我的实践包括 Intel 196、Infineon C166、Freescale HCS12、Renesas、x86、x86_64 和 ARM 架构。
    猜你喜欢
    • 1970-01-01
    • 2017-09-10
    • 2011-12-12
    • 2013-08-08
    • 1970-01-01
    • 2013-02-02
    • 2022-01-04
    • 2014-04-05
    • 1970-01-01
    相关资源
    最近更新 更多