【问题标题】:Variable conversion mixup in CC中的变量转换混淆
【发布时间】:2015-11-12 20:43:06
【问题描述】:

我有以下 C 代码,我必须理解为什么结果是一个相当大的正数:

int k;
unsigned int l;         
float f;
f=4; l = 1; k = -2; 
printf("\n %f", (unsigned int)l+k+f);

结果是一个非常大的数字(大约 40 亿,最大为 32 位整数),所以我怀疑它与有符号负整数(二进制补码)的表示有关,如果我们看它看起来相当大未签名。

但是我不太明白为什么它会以这种方式运行,以及浮动与这种行为有什么关系(如果我删除它,它就会停止这样做)。有人可以解释它是如何做到的吗?将导致此结果的数字相加时会发生什么过程?

【问题讨论】:

  • 查找与printf相关的类型强制
  • OP:阅读一本关于 C 的好书。SO 不是一个一站式商店,因为你懒惰自己做研究并找出答案阅读 C 标准,又名n1570

标签: c


【解决方案1】:

问题在于,当您将签名的int 添加到unsigned 时,C 会将结果转换为unsigned int,甚至是负数。因为k 是负数,所以在相加之前它会被重新解释为一个很大的正数。之后添加了f,但与重新解释为正数的负数 2 相比,它很小。

以下是问题的简短说明:

int k = -2;
unsigned int l = 1;
printf("\n %u", l+k);

这将在 32 位系统上打印 4294967295,因为在二进制补码表示中的 -20xFFFFFFFE (demo)。

【讨论】:

  • 谢谢,所以浮动实际上没有区别,这让我很困惑。
  • @user3604097 浮点数在您的代码中很重要,因为它可以防止未定义的行为,否则会导致使用 %f 打印 unsigned
  • 我认为浮动与不正确的转换有关,这让我感到困惑。所以完全是-2直接转为无符号。
【解决方案2】:

答案是,当编译器执行 l+k 时,它会将 k 类型转换为 unsigned int ,这会将它变成那个大数字。如果将 vars 的顺序更改为:l+f+k,则不会发生此行为。

【讨论】:

    【解决方案3】:

    发生的情况是,负整数通过将最大无符号值加一重复地添加到有符号值直到它可以表示,被转换为unsigned 整数。这就是为什么您会看到如此大的价值。

    使用二进制补码,它与截断或符号扩展值并将其解释为unsigned 相同,这对于计算机来说很简单。

    【讨论】:

      猜你喜欢
      • 2016-01-14
      • 1970-01-01
      • 1970-01-01
      • 2011-05-19
      • 2017-02-11
      • 2014-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多