如何在函数的 N 次递归调用中中断程序?

Posted

技术标签:

【中文标题】如何在函数的 N 次递归调用中中断程序?【英文标题】:How do I break a program at N recursive call of a function? 【发布时间】:2019-06-14 11:00:09 【问题描述】:

我的程序中有一个递归调用

Left?.Generate(ref result, ref resultGiven);

当这个Generate() 函数被调用6 次时,我想调试我的程序并停止执行。我该怎么做?

【问题讨论】:

添加一个计数器并在达到 6 时退出? 使用 Debugger.Launch() if counter = 6; 【参考方案1】:

最简单的方法是使用全局变量。

// somewhere before Generate first call
var counter = 0;

void Generate(ref result, ref resultGiven)

  if (counter == 6)
     return;
  counter++;
  // the rest of function's body
 

【讨论】:

您正在限制函数的 any 调用:Generate 的执行次数不能超过 6 次。但是,OP 似乎想要限制递归的深度Generate 不能调用自身超过6 次)。 @DmitryBychenko,我不确定,但主题名称中包含“破坏程序”字样,所以我认为这些情况之间没有区别。 @DmitryBychenko,哎呀,我只是想“中断程序”可能意味着“停止执行”而是“创建断点”。在这种情况下,您的方法当然是可取的。【参考方案2】:

如果我没有理解错,你想限制递归的深度(即不要让Generate 调用自己超过6次) .如果是你的情况,你可以试试StackTrace这个类:

using System.Diagnostics;

...

void Generate(ref result, ref resultGiven) 
  // --- Comment this out after debugging
  string currentFrame = new StackTrace(new StackFrame(false)).ToString().Trim();

  StackTrace trace = new StackTrace();

  int depth = trace
    .ToString()
    .Split(new char[]  '\r', '\n' , StringSplitOptions.RemoveEmptyEntries)
    .Where(frame => frame.Trim() == currentFrame)
    //.TakeWhile(frame => frame.Trim() == currentFrame) // if direct calls only
    .Count();

  // Prevent Generate to call itself more than 6 time 
  if (depth > 6) 
    // Maximum depth reached, return or launch debugger - Debugger.Launch()
    return;  
  
  // --- Comment this out after debugging

  ...

【讨论】:

不...只是不。不要对这么简单的事情使用反射。 这同时也是对反射最恶魔和最天才的使用!喜欢它! @riffnl:这不是那么简单。如果Generate 从例程的不同部分使用不同的参数调用会怎样?让我们加重一下:同时从不同的线程 所以这就是你添加参数的原因(例如默认为 0:不需要调整任何东西和线程安全)。为此使用反射就是用大锤敲碎坚果。【参考方案3】:

使用计数或步长参数就足够了;

Left?.Generate(ref result, ref resultGiven); // is same

函数看起来像这样:

void Generate(object ref result, object ref resultGiven, int step = 0)

  // do stuf

  // break for debug
  if (step >= 6)
  
    return; 
  
  // or only break when debugger is attached
  if (System.Diagnostics.Debugger.IsAttached && step >= 6)
  
    return; 
  
  // recursive
  Generate(ref result, ref resultGiven, step++);

【讨论】:

这还不够(一般情况下):假设Generate 调用方法Foo 调用Generate。在您的方法中,我们也必须更改Foo 没错,但这不再是(严格来说)递归了。

以上是关于如何在函数的 N 次递归调用中中断程序?的主要内容,如果未能解决你的问题,请参考以下文章

C语言 递归程序 求解

如何在matlab中利用函数的递归调用求n!

递归函数

1113: 递归调用的次数统计(函数专题)

1113 递归调用的次数统计

c语言怎么用递归调用函数的方法求n的阶乘?