私はその実装で再帰を使用するいくつかのコードを持っています。 profiler which I'm usingは再帰関数呼び出しではうまくいかないので、再帰的でないように書き直したいと思います。再帰を避ける
void Parse(Foo foo)
{
A()
for (;;)
{
B();
if (C())
return;
if (D())
{
Run();
}
E();
}
}
void Run()
{
X();
if (Y())
{
Parse();
}
Z();
}
上記で擬似コード:
現在のコードは次のようなものです。文字A、B、C、D、E、X、Y、Zはメソッドであり、Parse()とRun()も同様です。わかりやすくするために、私はさまざまなパラメータとオブジェクトの逆参照を除外しました(たとえば、Runはオブジェクトインスタンスのメソッドであり、いくつかのパラメータが必要です)。
とにかく、私の質問は、これを非再帰的コードにするにはどうすればいいですか?
同等の非再帰的コードがあることを私には思える:
void Parse(Foo foo)
{
//create a local stack variable to emulate recursion
Stack<Foo> foos = new Stack<Foo>();
foos.Add(foo());
start_subroutine:
A()
for (;;)
{
B();
if (C())
{
//instead of returning from a recursive call
if (foos.Count > 1)
{
foo = foos.Pop();
goto end_subroutine;
}
return;
}
if (D())
{
//instead of invoking Run as a subroutine, bring its functionality inline
//Run();
X();
if (Y())
{
//instead of calling self recursively
//Parse();
//push onto a local stack variable and jump
foos.Add(foo);
goto start_subroutine;
}
end_subroutine:
Z();
}
E();
}
}
私はこれを行うといいんだけど、私はgoto文を使用せずにそれを行うにはどのように表示されていません。 gotoが必要な場合の1つであると誰かが書いていることをいつも覚えていることは覚えていません。
プロファイラの脆弱性に合わせてコードを書き直す考えは、最近私が遭遇したのが一番奇妙です。 –
私はCの人々が行う「奇妙なこと」の増加するリストにそのことを言います –
@Dirk - 私はそれがこの道を導いたのはフリーソフトウェアの追求だと思います。 – ChrisF