Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何使用内联递归?_C++_Recursion_Programming Languages_Inline_Computer Science - Fatal编程技术网

C++ 如何使用内联递归?

C++ 如何使用内联递归?,c++,recursion,programming-languages,inline,computer-science,C++,Recursion,Programming Languages,Inline,Computer Science,从、关于衬里和递归: 在线扩展在一般情况下也不是一种选择 递归子程序。对于偶尔出现的递归 调用是可能的,但不太可能,生成真实的 递归子例程,但要扩展该例程的一个级别 在每个呼叫站点在线 作为一个简单的例子,考虑一个包含叶子的二叉树。 字符串。返回此树边缘的例程( 从左到右连接其叶中的值)可能看起来 在C++中类似这样: string fringe(bin_tree *t) { // assume both children are nil or neither is if (t-

从、关于衬里和递归:

在线扩展在一般情况下也不是一种选择 递归子程序。对于偶尔出现的递归 调用是可能的,但不太可能,生成真实的 递归子例程,但要扩展该例程的一个级别 在每个呼叫站点在线

作为一个简单的例子,考虑一个包含叶子的二叉树。 字符串。返回此树边缘的例程( 从左到右连接其叶中的值)可能看起来 在C++中类似这样:

string fringe(bin_tree *t) {
    // assume both children are nil or neither is
    if (t->left == 0) return t->val;
    return fringe(t->left) + fringe(t->right);
}
如果编译器使每个嵌套调用都成为真正的子例程调用,那么它可以在线扩展此代码。因为有一半的节点是二进制的 树是叶子,这种扩展将消除一半的动态调用 在运行时

如果我们不仅扩展根调用,还扩展(一级)两个调用 在真正的子例程版本中调用,只调用 原始动态调用将保留

我无法理解以下句子:

  • “在每个呼叫站点在线扩展该例程的一个级别”
  • “如果此代码使每个嵌套调用成为真正的子例程调用,请将其展开。”
  • “不仅展开根调用,而且展开真正子例程版本中的两个调用(一个级别)”
它们实际上是什么意思?你能用给定的例子来解释它们吗?例如,在每个句子的动作完成后,展示代码是什么样的


谢谢。

一些编译器可以扩展和内联嵌套的递归调用

例如,下面的代码(我没有使用
inline
关键字!):

请注意,
fact
已经完全内联,并且没有出现在生成的汇编代码中

“在每个呼叫站点在线扩展该例程的一个级别”

这意味着
f5
将被编译成

int f5() { return 5*fact(4); }

fact
出现在生成的代码中并编译成递归(机器码)函数(使用调用堆栈)时。

到目前为止,理解这一点最简单的方法是将内联看作是创建一种替代的二进制表示。例如,除了创建基本的
字符串边缘(bin_树*t)
,编译器还可以决定创建
字符串边缘内联(bin_树*t)
。而在
borge\uu inlined
中,实际的内联函数将是
borge
的一个或两个副本

甚至可以通过这种方式创建一个
边缘\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuinlined
(如上所述,两个级别)

你能用给定的例子来解释它们吗,例如,展示代码是什么样的

<>注释:编译器/优化器不在编写的C++代码上执行这些操作,而是在某些内部表示上执行这些操作。可以用C++来演示这个概念,但是由于语法和可读性问题,我们可能需要引入额外的更改,例如临时变量。 在每个调用站点在线扩展该例程的一个级别

变成

if (t->left == 0) result = t->val;
else result = fringe(t->left) + fringe(t->right);
在真正的子例程版本中,不仅展开根调用,而且展开(一级)两个调用


代码与原样完全相同,但编译器可以决定内联一个调用,也可以保留同一函数的非内联版本。
int f5() { return 5*fact(4); }
result = fringe(t);
if (t->left == 0) result = t->val;
else result = fringe(t->left) + fringe(t->right);
if (t->left == 0) result = t->val;
else {
    string left, right;

    // one level of expansion for left subtree
    if (t->left->left == 0) left = t->left->val;
    else left = fringe(t->left->left) + fringe(t->left->right);

    // one level of expansion for right subtree
    if (t->right->left == 0) right = t->right->val;
    else right = fringe(t->right->left) + fringe(t->right->right);

    result = left + right;
}