如何跟踪递归深度
How do I track recursion depth?
我有一个递归函数,我正在排除故障。我想输出递归深度…函数调用自己的次数
如果我使用一个静态变量,在函数的顶部递增,在底部递减。
这能准确地给出深度等级吗?
recurse()
{
static int depth = 0;
depth++;
/*
do stuff
recurse()
*/
depth--;
return return_value;
}
recurse(int depth = 0){
....
recurse(depth+1);
}
为了方便,
- 异常安全
- 线程安全的
- 支持树递归
<子>如果您真的发挥您的想象力,这可以使编译器更容易内联一些递归调用,和/或在尾部递归的情况下执行尾部调用优化。我没有证据表明这起作用,但我可以想象从函数体中引用外部符号会影响编译器优化。 子>
我建议:
stuff recurse(int level=0)
{
//...
recurse(level+1);
//... (return stuff?)
//... (throw exceptions?)
//...
recurse(level+1);
//... (return stuff?)
}
不,如果抛出异常,它可能不会。一个更好的(也是更常见的)选项是:
int recurse(int depth=0)
{
recurse(depth+1)
return return_value;
}
如果你想做这件非侵入性的事情,你可以让你的编译器为你检测每次调用,例如使用gcc:
#include <iostream>
static __thread int depth=-1;
extern "C" {
void __cyg_profile_func_enter (void *, void *) __attribute__((no_instrument_function));
void __cyg_profile_func_exit (void *, void *) __attribute__((no_instrument_function));
void __cyg_profile_func_enter (void *func, void *caller)
{
depth++;
}
void __cyg_profile_func_exit (void *func, void *caller)
{
depth--;
}
}
class Foo {
public:
void bar() {
std::cout << "bar: " << depth << std::endl;
}
};
int main() {
Foo f;
f.bar();
return 0;
}
您需要使用-finstrument-functions
进行编译才能使其工作
出于线程安全的目的,通常需要增加在递归函数外部定义的深度变量,并从该函数外部打印它。
下面是一个简单的阶乘示例:
#include <stdio.h>
unsigned factorial(unsigned x, unsigned* depth)
{
if (x <= 1)
return 1;
++*depth;
return x * factorial(x - 1, depth);
}
int main(void)
{
unsigned depth, f;
depth = 0; f = factorial(1, &depth);
printf("factorial=%u, depth=%un", f, depth);
depth = 0; f = factorial(2, &depth);
printf("factorial=%u, depth=%un", f, depth);
depth = 0; f = factorial(6, &depth);
printf("factorial=%u, depth=%un", f, depth);
return 0;
}
输出:C:>recdep.exe
factorial=1, depth=0
factorial=2, depth=1
factorial=720, depth=5
在单线程上下文中可以工作。
是的,它应该工作。
相关文章:
- 通过递归进行因子分解
- 递归函数计算序列中的平方和(并输出过程)
- 使用递归的数组的最小值.这是怎么回事
- 使用后序遍历递归的深度优先搜索会产生意外输出
- 由于深度递归而导致堆栈溢出
- 5000+ 深度递归时函数堆栈溢出
- OpenMP:即使在深度极限的情况下,递归任务也比顺序慢
- 可变参数模板实例化中的无限递归,试图构建任意深度的树状结构
- lambda 的深度递归
- C++递归函数,调用当前深度
- 递归的最大深度是多少?
- 查找最大递归深度
- 如何跳出一些深度递归的函数并直接返回结果
- 如何跟踪递归深度
- 如何改进此模式所需的模板递归深度
- 递归深度切断策略:并行快速排序
- 具有合成和继承属性的深度递归qi语法(解析器)
- 为什么这超过了递归模板的最大深度
- 递归模板实例化超出了最大深度 256
- 深度优先搜索或回溯递归查找字谜/拼字板中所有可能的字母组合