【问题标题】:Difference in type conversion between C and C++?C和C++之间类型转换的区别?
【发布时间】:2015-11-26 22:43:19
【问题描述】:

this tutorial 中关于隐式类型转换的最后一个示例指出,由于类型转换,std::cout << 5u - 10; 将生成 4294967291 而不是 -5。 我在 C 和 C++ 中都试过这个。 C++ 中的结果如所承诺的那样,但是当使用 C (printf("%d\n", 5u - 10);) 时,结果是-5。 发生了什么?

【问题讨论】:

标签: c++ c type-conversion


【解决方案1】:

稍加思考后,我们意识到问题出在printf 而不是转换本身。 请注意,写的是printf("%d")。这执行了又一次转换回signed int,这就是为什么我看到-5的结果。

使用printf("%u") 进行测试时,显示了承诺的结果(4294967291)。

为了结束它,printf("%X") 产生了FFFFFFFB,这意味着这两个值,取决于有符号或无符号的解释。

【讨论】:

  • 我认为您的意思是“又一次转换回 signed int”
  • printf 不执行基于格式说明符的转换。它假定数据是正确的类型,否则会导致未定义的行为。
  • 确实 - 在内部表示 intunsigned 之间存在没有区别。没有进行“转换”,只是根据类型处理相同的数据。
  • 为什么人们赞成这个?在不使用 2 的补码的编译器中运行代码,会发生令人惊讶的事情,您会看到没有应用任何转换。 printf 没有类型的概念,只是将字节视为指定的格式
【解决方案2】:

在 C 示例中,没有任何类型转换。 C 只计算表达式5u - 10 并将结果压入堆栈。然后 printf 看到一个类型字符并在打印时解释堆栈上的值。类型字符是d (%d),意思是“十进制整数”,因此堆栈上的位置被检索为 int 并打印为(有符号)十进制。

如果类型字符是例如ld (%ld),堆栈上的位置将作为 long 检索,即使只推送了一个 int,并且将打印为(有符号的)十进制数字。同样,没有任何类型转换(只会打印一个无意义的数字)。

【讨论】:

  • 正在进行整数提升以进行计算。至于printf,我同意你的看法——我措辞不正确。
  • @levengli,我相信签名或未签名的 int 都没有“提升”。默认情况下以整数的宽度(有符号或无符号)进行计算。在常量表达式中,从数字 5(无论有符号还是无符号)中减去数字 10。减法“包装位”,如果解释为无符号则产生一个很大的数字,而当解释为有符号时则为 -5。
  • 进行算术运算时,运算符的两边需要是相同的数据类型。 5uunsigned10signed(默认)。结果,发生整数转换。请参阅 c99 规范的“6.3.1.8 常用算术转换”部分
  • @levengli,这只是一个理论论证。 unsigned 5、signed 5 的按位表示和 unsigned 10 和signed 10 的按位表示是相同的。因此,没有真正的促销活动发生。我不在乎编译器是否会在内部使用浮点数来计算常量表达式,只要它将正确的结果放入目标文件(可以解释为无符号 4294967291 或有符号 -5 的整数宽度的位集) .
  • 对于正数,int 和不大于 2^31 的值,您是正确的
猜你喜欢
  • 2011-05-19
  • 2010-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-15
  • 1970-01-01
  • 2021-12-06
相关资源
最近更新 更多