0

重複の可能性:
while ループの代わりに for ループを使用するのはなぜですか?

私は現在埋め込みcを使用しています。私が使用しているソフトウェアは keil uvision です。

それで、どのループを使用するかについて質問がありますか? どちらのループもまったく同じことを行います。signal = 0 である限り、「i」は 1 ずつ増加します。

まず、

for(;signal==0;)
{
    i++;
}

次のプログラム:

while(signal==0)
{
    i++;
}

では、どのループを使用し、その理由は? 両者の違いは何ですか?実行にかかる時間に違いはありますか?それとも純粋にあなたの好みに基づいていますか?

4

6 に答える 6

6

一般的に言えば、for反復回数がわかっている場合 (つまり、配列内の各要素について) はループが好まれ、ループwhileを実行する回数がわからない場合は、より一般的な条件でループが適しています。ただし、forループはループでできることは何でもできますwhile。それはすべて、どちらがコードをより読みやすくするかによって異なります

この場合、false になるのを待っていて、それがいつ発生するかわからないため、whileループが望ましいでしょう。signal == 0

于 2012-08-07T02:44:56.513 に答える
3

任意forのループをループで記述できwhile、その逆も可能です。あなたがすることは、好み、慣習、読みやすさの混合です。

通常、forループはカウントに使用され、ループwhileは特定の条件 (ファイルの終わりなど) が満たされるのを待っています。性能差はありません。

ボイラープレートforwhileループ:

for(int i = 0; i < someArraysLength; i++)
{
    // Modify contents of array
}

while(lineLeftInFile)
{
   // Read and parse the line
}
于 2012-08-07T02:43:01.423 に答える
2

どちらが読みやすく、理解しやすいか。
ある時点で (あなた以外の) 誰かがあなたのコードを読み取ろうとする可能性があることに注意してください。

私の意見:while

于 2012-08-07T02:38:18.323 に答える
1

実行時間は関係ありません。いまいましい価値のあるコンパイラは、まったく同じコードを生成します。

さて、セマンティクスなどについては...計算上、

for (init; test; increment) { /* do stuff */ }

とまったく同等です

init;
while (test) {
    /* do stuff */
    increment;
}

そして なしinitincrement, だけになります

while (test) {
    /* do stuff */
}

したがって、計算上、この 2 つは同一です。ただし、意味的には、forループは、セットアップおよび/またはインクリメント ステージある場合に使用されます (特に、反復回数が予測可能な場合)。そうでないので、 に固執しwhileます。

于 2012-08-07T02:48:05.400 に答える
0

では、どのループを使用し、その理由は?

2 つのうちどちらかを選択する必要がある場合は、おそらくwhileループを使用します。ループはよりシンプルでクリーンであり、シグナルが更新されるまで次のコード ブロックが継続的に実行されることを他の開発者に明確に伝えます。

もう一度これを行うことができfor(; signal == 0; i++);ます。これが実際に製品コードになるかどうかを前提としていますが、より簡潔なようです。

それでも、このすべてのメソッドは、オーバーフローのために少し危険に思えます。組み込みデバイスでさえ、ほとんどのクロックは依然として非常に高速であり、おそらく基になるデータ型の上限にすぐに達するでしょう。これが本番になるかどうかはわかりません。コードも、それが許容できる結果であるかどうかもわかりません。

両者の違いは何ですか?

forあなたが言ったように、両方とも同じ目標を達成しますが、私が示したように、または他の人が言及したように、他の方法があると確信してwhileいます.良くも悪くも、非常にfor柔軟な の非常にユニークな使い方を見てきました。

実行にかかる時間に違いはありますか?それとも純粋にあなたの好みに基づいていますか?

パフォーマンスに関しては、基本的にコンパイラがそれをどのように解釈するかを決定します。同じバイナリを生成する場合と生成しない場合があるため、実行時間は、アセンブリを生成するか、プロファイリングを実行するようにコンパイラに依頼できます。

uvision 4 IDE http://www.keil.com/product/brochures/uv4.pdfは実際に 94 ページに記載されているように逆アセンブルをサポートし、103 ページに記載されているようにプロファイリングをサポートしているようです。使用しています。

違いが十分に小さい場合は、数ナノ秒余分に圧縮するためだけに読みやすさを犠牲にしないでください。これは単なる私の意見です。

私があなたに与えることができる最善のアドバイスはこれです。できる限り最善を尽くして、明確なコードを書くことです。つまり、ほとんどの人は、それほど努力せずに何を伝えているかを見ることができます。それは効率的で保守しやすいということです。

于 2012-08-07T04:56:26.153 に答える
0

私は mariusnn に同意しますが、どちらが読みwhileやすく、私にとっても読みやすいと思われます。

デバッグ ビルドの実行時に Visual Studio 2005 によって生成されたアセンブラを見ると、これらのループの両方でアセンブラの命令が同じように見えます。実際、if ステートメントとラベルを使用して同じループを実行すると、true ステートメントが i をインクリメントしてから再び if ステートメントに移動すると、同じアセンブラーが生成されるように見えます。

    for (; signal == 0; ) {
0041139C  cmp         dword ptr [signal],0 
004113A0  jne         wmain+3Dh (4113ADh) 
        i++;
004113A2  mov         eax,dword ptr [i] 
004113A5  add         eax,1 
004113A8  mov         dword ptr [i],eax 
    }
004113AB  jmp         wmain+2Ch (41139Ch) 

    while (signal == 0) {
004113AD  cmp         dword ptr [signal],0 
004113B1  jne         loop (4113BEh) 
        i++;
004113B3  mov         eax,dword ptr [i] 
004113B6  add         eax,1 
004113B9  mov         dword ptr [i],eax 
    }
004113BC  jmp         wmain+3Dh (4113ADh) 

loop: if (signal == 0) {
004113BE  cmp         dword ptr [signal],0 
004113C2  jne         loop+11h (4113CFh) 
        i++;
004113C4  mov         eax,dword ptr [i] 
004113C7  add         eax,1 
004113CA  mov         dword ptr [i],eax 
        goto loop;
004113CD  jmp         loop (4113BEh) 
      }
于 2012-08-07T03:00:00.220 に答える