代码之家  ›  专栏  ›  技术社区  ›  Aaron

Perl中深层调用堆栈的潜在含义是什么?

  •  1
  • Aaron  · 技术社区  · 16 年前
    • 我听说下面的代码部分是非常递归的。但是我不明白怎么解释-有人能解释吗?
    • 如果是,相关的含义是什么?

    注:

    微不足道的例子

                check:
                # Grab some data held in a file
                while ((ReadFile ()) != 0 ) { 
                        if ((checkSomething ()) != 1) {
                                # value found, check file again
                                next check;
                        } else {
                                blah ($doo, $foo);
                        }
                }
    

    更新:

    • 感谢您的更正。
    • 以下关于内存消耗的含义是什么?据我所知,在回顾其他问题之后,这不是递归:

      sub D {
              ..
      }
      sub C {
              D ();
      }
      sub B {
              C ();
      }
      sub A {
              while (true) {
                      B ();
              }
      }
      
    4 回复  |  直到 16 年前
        1
  •  8
  •   Dan    16 年前

    第二个例子也不是递归的例子。这只是一个我非正式地称之为“链式子程序调用”的例子——我不相信有一个正式的术语。递归要求子例程直接或通过一些中介调用自身。

    例如,如果子例程d在某些条件下调用了a、b或c,那么这就是递归。

    对于深度调用堆栈,答案取决于:

    • 有多深
    • 你们每个人要传递多少个论点
    • 程序可以分配多少内存

    每次调用子例程时,它都会在调用堆栈上添加一个新帧。在子程序完成之前,该帧保持不变。这个堆栈帧的大小主要取决于参数列表的长度,加上一些固定的开销。

    所以在本例中,您将得到一个包含四个元素的堆栈框架。

    如果调用链太深,并且每个条目都有一个很长的参数列表,那么最终将耗尽调用堆栈的空间。这称为堆栈溢出。:)

        2
  •  4
  •   JSBÕ±Õ¸Õ£Õ¹    16 年前

    正如其他人所说,您的代码不是递归的,所以不要担心它。但是,如果你消除无用的东西,它会更干净,更容易阅读。 if 通过为 else 将唯一的一个分支,并去掉粘性标签:

    while ((ReadFile ()) != 0 ) { 
        if ((checkSomething ()) == 1) {
            blah ($doo, $foo);
        }
    }
    
        3
  •  3
  •   Cheeso    16 年前

    代码中没有递归。

    您的代码可能有递归,但它没有显示在您提供的代码中。

        4
  •  0
  •   aaaa bbbb    16 年前

    我同意JSBangs的观点,但另一个替代恶心标签的方法是使用continue语句,而不是“next check”。JSBangs是最好的代码,但是Continue语句有它们的位置。