のように見える
while( condition ) {
//do stuff
}
と完全に同等です
for( ; condition; ) {
//do stuff
}
前者の代わりに後者を使用する理由はありますか?
のように見える
while( condition ) {
//do stuff
}
と完全に同等です
for( ; condition; ) {
//do stuff
}
前者の代わりに後者を使用する理由はありますか?
私の知る限り、正当な理由はありません。何もインクリメントしない for ループを使用して、意図的に人々を誤解させています。
アップデート:
質問に対するOPのコメントに基づいて、実際のコードでそのような構造がどのように見えるかを推測できます。私はこれを以前に見た(そして使用した):
lots::of::namespaces::container::iterator iter = foo.begin();
for (; iter != foo.end(); ++iter)
{
// do stuff
}
しかし、それは、for ループから物事を除外することで行く限りです。あなたのプロジェクトには、かつてそのようなループがあったかもしれません。ループの途中でコンテナーの要素を削除するコードを追加する場合は、iter
インクリメント方法を慎重に制御する必要があります。これにより、次のようなコードになる可能性があります。
for (; iter != foo.end(); )
{
// do stuff
if (condition)
{
iter = foo.erase(iter);
}
else
{
++iter;
}
}
ただし、while ループに変更するのに 5 秒もかからないという言い訳にはなりません。
一部のコンパイラは、一定のループ条件について警告します。
while (true) { /* ... */ } /* Warning! */
for (;;) { /* ... */ } /* No warning */
無限ループの特定のケースでは、そのため、while ループよりも for ループを選択することがあります。しかし、条件が空でない場合、私には何のメリットもありません。言及されたプロジェクトになぜそれが現れたのかについての私の推測では、コードはメンテナンスによって何らかの形で進化しましたが、もともとはより従来の方法で書かれていました。
ダメダメダメ。
微視的なパフォーマンスの違いがあったとしても、それを十分に気にするためには、最終段階のジェダイパフォーマンスチューナーである必要があります。
コンパイル可能です
for(INIT; CONDITION; UPDATE)
{
BODY
}
の中へ
{
INIT
while(CONDITION)
{
BODY
UPDATE
}
}
更新:一見冗長な余分なスコープは、INIT 内の変数定義、つまり from をケージに入れることですfor(int i = 0; ...)
。ありがとう!
基本的には、式の並べ替えにすぎません。したがって、パフォーマンス上の理由から、どちらかを優先する理由はありません。while()
できれば簡単なのでおすすめです。より単純な構成でやりたいことを表現できるのであれば、それを使うべきだと思います。
私の知る限り、この 2 つのステートメントはコンパイラによって同じアセンバー コードに最適化されます。だからいいえ、そうする理由はありません。個人的な好みです。
「while」ループと「for」ループは、異なるイディオムを対象としていると思います。「while」を使用するイディオムは、「特定の条件が真である間に何かを行う」です。「for」のイディオムは「特定の範囲の要素を繰り返す」...
コードを読むときはいつでも、これらのイディオムを期待します (そして、私は一人ではないと思います)。「for」が表示されると、誰かが特定の範囲を反復していることがわかりますが、詳細には触れません。for サイクルが別のイディオムに使用されているのを見ると (私が予想するものではない)、混乱して詳細に入る必要があります。
とにかく主観がすごい…
この場合、個人的には最初のループの方が読みやすく書きやすいので好みです。
しかし、ステートメントを投稿する必要があるループがある場合は、次のように for ループを使用します。
for (; i < 10; i += 2)
アセンブリ レベルではコンパイラに依存する小さな違いがあるかもしれませんが、両方がまったく同じように動作し、前者の方が読みやすいことが理想的です。いいえ、不適合以外に後者のバージョンを使用する理由はありません。
両方をコンパイルし、結果の逆アセンブルを確認します (同じである可能性があります)。最も読みやすいものを選択してください。
私は2つの理由を見ることができますが、どれも私は考えません:
この質問には答えがあります - 言語には、あなたが望むものを表現するためのより自然な構造があります - あなたはそれを使うべきです. たとえば、私は確かにこれを書くことができます:
for (bool b = condition(); b; b = !b) {
/* more code */
}
また:
while (condition()) {
/* more code */
break;
}
より従来の代わりに:
if (condition()) {
/* more code */
}
しかし、なぜ?C (およびすべての言語) にはイディオムがあり、そのほとんどは表現力と意味の期待という点で合理的な意味を持ちます。イディオムをいじると、あなたのコードを読まなければならない人の感性を台無しにします。
私はかなり難解な C/C++ コードを書いていました。振り返ってみると、おそらくwhileループでこれを行うでしょう:
ifstream f("file.txt");
char c;
for(f.get(c); !f.eof(); f.get(c)) {
// ...
}
私の要点は、 for ループは通常、範囲をループするという従来の意味で使用されていない場合、通常は短くなりますが、読みにくくなるということです。
C っぽい言語では、for (;cond;) ループと while ループの間に違いはありません。一般的に、私が C っぽい言語で行うことは、ループを「for」として書き始め、その形式になったら「while」に変更することです。ただし、常に何かを繰り返し処理しているため、C では最後の領域に任意のコードを配置できるため、これはまれです。
C に実際の(事前に計算された) for ループがある場合は異なります。
読みやすさはしばらく置いておきますが、通常、異なるループ間でパフォーマンスの違いはありません。少なくとも大きな違いはありません。
デスクトップ アプリケーションの場合は、読みやすさの基準に基づいて選択できます。他の投稿を参照してください - たとえば for ループを見ると、インクリメンタがループ内で宣言されていると誰かが考えています。
クライアントサイドスクリプトなどのWebアプリケーションには違いがあるようです。
このサイトを確認してください: http://www.websiteoptimization.com/speed/10/10-2.html
独自の実験を実行し、結果に基づいてください。それ以外の場合は、読みやすさのルールに従ってください。
限られた回数だけ何かを実行したい場合は、「for」を使用して、ループ内のロジックとごちゃ混ぜにせずに制約を指定できます。
for ループの代わりに do-while ループを使用して、条件がチェックされて満たされる (または満たされない) 前にコードが少なくとも 1 回処理されるようにすることもできます。