考虑到b总是非零,为什么`b? --b:++ b`工程,但`--b不是? [英] Given that b is always non-zero, why `b ? --b : ++b` works, but `--b` does not?

查看:138
本文介绍了考虑到b总是非零,为什么`b? --b:++ b`工程,但`--b不是?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用递归乘以两个整数,并且意外地写了这个代码:

I was trying to multiply two integers using recursion, and wrote this code, accidently:

//the original version
int multiply(int a, int b)
{
  if ( !b )
     return 0;
  else
     return a + multiply(a, b ? --b : ++b ); //accident
}



我说过,这是不经意写的,因为我打算写:

I said, I wrote this accidently, because I intended to write :

b> 0? --b:++ b 而不是 b? --b:++ b

我意识到我打算写无法工作。但对我来说,令人惊讶的是,我打算写工作

I realize that what I intended to write wouldn't work. But what is surprising to me is, what I did not intend to write does work.

现在,我注意到 b? - b:++ b 基本上等同于 -b ,因为else-block中的 b 保证为非零。所以我修改了上面的代码,用 - b 替换 b? - b:++ b 下面:

Now, I note that b ?--b : ++b is basically equivalent to --b because b in else-block is guaranteed to be non-zero. So I modified the above code, replacing b?--b:++b with --b, as shown below:

//the modified version
int multiply(int a, int b)
{
  if ( !b )
     return 0;
  else
     return a + multiply(a, --b); //modification here
}

由于原始版本woks,我预计修改版本工作以及。但是,令我吃惊的是,无法正常工作!

Since the original version woks, I expected the modified version to work as well. But again, to my surprise, it doesn't work!


  • 修改后的版本有什么问题?

  • 它不等同于原始版本吗?

  • - b 不等同于 b? - b:++ b IF b 不为零?如果它的等价,那么为什么第一个代码工作,但第二个不?

  • What is wrong the modified version?
  • Is it not equivalent to the original version?
  • Is --b not equivalent to b ?--b : ++b IF b is non-zero? If its equivalent, then why does the first code work but the second doesn't?

注意:在这里,通过work,我的意思是它给出正确的输出。

Note: here, by "work", I mean it gives the correct output. That is, it gives the multiplication of the integers passed to the function.

推荐答案

TL; DR版本:原因 b? --b:++ b 打印结果, - b 失败, SIGXCPU 是ideone对提交的代码设置时间限制。一个版本被更好地优化,并在允许的时间内完成。其他版本给出完全相同的答案,但你不会看到与ideone,因为它运行太慢,被中止的时间限制。

TL;DR version: The reason b? --b: ++b prints a result and --b fails with SIGXCPU is that ideone sets a time limit on submitted code. One version gets optimized better, and completes in the time allowed. The other version gives the exact same answer, but you won't see that with ideone because it runs too slowly and gets aborted by the time limit.

至于为什么堆栈溢出不会发生,我想在一种情况下,编译器必须将递归转换为迭代(这不是一个尾调用,但它是trivially可变换)。

As for why the stack overflow isn't occuring, I guess in one case the compiler must be transforming recursion into iteration (this isn't a tail call, but it is trivially transformable).

转换的结果将类似于 http://ideone.com/ AeBYI ,它的确给出了正确的结果。使用更高的优化设置,编译器可以在编译时计算结果,并在结果代码中存储常量。

The result of the transformation would be something like http://ideone.com/AeBYI which indeed gives the correct result. With higher optimization settings, the compiler could calculate the results at compile time and store constants in the resulting code.

这篇关于考虑到b总是非零,为什么`b? --b:++ b`工程,但`--b不是?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆