7

そのため、BFS アルゴリズムでノードをバックトラッキングするための C++ コードがいくつかあります。次のようになります。

typedef std::map<int> MapType;
bool IsValuePresent(const MapType& myMap, int beginVal, int searchVal)
{
    int current_val = beginVal;
    while (true)
    {
        if (current_val == searchVal)
            return true;

        MapType::iterator it = myMap.find(current_val);
        assert(current_val != myMap.end());
        if (current_val == it->second) // end of the line
            return false;
        current_val = it->second;
    }
}

しかし、while (true)私には疑わしいようです。私はこのコードが機能することを知っており、論理的に機能するはずであることを知っています。ただし、 に何らかの条件が必要であるという気持ちを揺るがすことはできませんwhileが、実際に可能な唯一の方法は、bool変数を使用して、それが完了したかどうかを示すことです。心配するのをやめるべきですか?それとも、これは本当に悪い形ですか?

編集:これを回避する方法があることに気づいてくれてありがとう。ただし、他に有効なケースがあるかどうかを知りたいです。

4

12 に答える 12

22

一見無限ループに見えてもいい場合もあると思います。ただし、これはそれらの 1 つではないようです。次のようにコードを書くのと同じくらい簡単にできるようです

while (current_val != searchVal ) {
    MapType::iterator it = myMap.find(current_val);
    assert(current_val != myMap.end());
    if (current_val == it->second) // end of the line
        return false;
    current_val = it->second
}
return true;

これはループの真意をよりよく表しているようです

于 2009-06-02T23:36:15.653 に答える
13

私の 2 セントは次のとおりです。コードは自己文書化する必要があります。つまり、コードの一部が与えられたときに、プログラマーの意図を見て伝えることができれば、コメントを読んだり、周囲のコードをたどったりする必要があります。私が読んだとき:

while(true)

これは、プログラマーが無限ループを望んでいたことを示しています。終了条件が指定できませんでした。これは、状況によってはプログラマーの意図です。たとえば、サーバーループであり、それが使用されるべきときです。

上記のコードでは、ループは永遠に続くことを意図したものではなく、明確な終了条件があり、意味的に明確にするために、他の人が指摘したように:

while (currentVal != searchVal)

動作するため、 while(true) は明らかに劣っており、この場合は避ける必要があります。

于 2009-06-03T00:00:45.073 に答える
6

無限ループには時と場所があります。これがその 1 つであるとは確信していません。一方で、ここでは深刻な問題ではありません。

while (currentVal != searchVal)
{
    ...
}
return true;

それらを使用する場所の 1 つは、プロセスが本当に不定である場合です。つまり、終了しないモニター ループを持つデーモン プロセスです。

于 2009-06-02T23:36:50.800 に答える
5

この場合、無限ループは必要ないという他の回答に同意します。

ただし、無限ループがある場合は、それを表現するためのより良い方法かもしれませんfor(;;)一部のコンパイラはwhile(true)(条件は常に false と評価されます) に対して警告を生成しますが、他のループのように見えるため、意図が明確ではありません。おそらく、以前は と言っていたのに、誤って の代わりに をwhile (x == true)削除してしまったのでしょう。これは無限ループを意図していることを明確に示しています。あるいは、 のようなものを書くつもりだったのに、IDE の Intellisense が作動して、 にオートコンプリートすることにしたのかもしれません。xtruefor(;;)while(t)true

for(;;)一方、誤って入力することはありません。(そして、検索する方が簡単です。while(true) は while(1) と書くこともできます)

どちらのバージョンも間違っていませんが、ループ条件for(;;)ないため、より直感的になる可能性があります。

于 2009-06-03T00:27:52.213 に答える
5

このような構造が理にかなっている状況があります。

  1. ブレーク条件はループ内で計算されます
  2. より多くの破壊条件があり、それらはすべて等しく重要です
  3. あなたは本当に無限ループが欲しいです;)..
于 2009-06-02T23:39:00.970 に答える
4

while(true)メイン ゲーム ループのゲームで使用されます。ゲームは継続的にプレーヤーの入力を読み取り、オブジェクト間の相互作用を処理し、画面をペイントしてから繰り返します。このループは、他のアクションがそのループから抜け出す (ゲームを終了する、レベルを終了する) まで無限に続きます。

Quake 1 のソース コードでこのメイン ループをすばやく見つけようとしましたが、「 」が少なくとも 50 回出現し、「while(1)」と書かれfor(;;)たものもあり、どれがメイン ゲームであるかすぐにはわかりませんでした。ループ。

于 2009-06-03T00:10:46.007 に答える
1

私は以前にそれらを行ったことがありますが、読み取り可能なものを使用して、より明確な解決策を常に模索することに投票します。これには、通常、while ループに有効な式が含まれます。それ以外の場合は、コードをスキャンしてブレークを探します。 .

私は彼らを本当に恐れているわけではありませんが、何人かの人々がそうであることは知っています.

于 2009-06-02T23:57:10.183 に答える
0

組み込みシステム コードで無限ループを見つけることは珍しくありません。多くの場合、有限ステート マシンを取り囲み、周辺機器のチップやデバイスをチェックするなどです。

于 2009-06-03T00:33:58.080 に答える
0

まあ、実際には無限ループではないというコメントが役立ちます。

    while (true) // Not really an infinite loop! Guaranteed to return.

条件が必要であることに同意しますが、状況によってはこれで問題ありません (また、条件を設定することが常に可能または簡単であるとは限りません)。

于 2009-06-02T23:33:43.990 に答える
0

心配しないで。コードのロジックを簡素化し、保守性と可読性を向上させるのに役立つ場合、これは悪い形式ではありません。予想される終了条件と、アルゴリズムが無限ループに陥らない理由についてコメントで文書化することは価値があります。

于 2009-06-02T23:40:21.637 に答える
0

はい、そうですが、メイン ループを次のようなものにしたくない場合に記述しなければならない 2 ページのコードwhile(true)は、さらに悪い形式です。

于 2009-06-02T23:44:56.993 に答える
0

有限ステート マシンの外部制御構造としての無限ループが大好きです。これは事実上、構造化された goto です。

for (;;) {
    int c = ReadInput();
    if (c == EOF)
        return kEOF;

    switch (state) {
    case inNumber: state = HandleNumber(c); break;
    case inToken: state = HandleToken(c); break;
    case inWhiteSpace: state = HandleWhiteSpace(c);
    default:
       state = inError;
       break;
    }
    if (state == inError) ThrowError();

}

于 2009-09-01T17:54:25.487 に答える