Cには、for
、while
、およびdo-while
の3つのループがあります。それらの違いは何ですか?
たとえば、ほとんどすべてのwhile
ステートメントをfor
ステートメントに置き換えることができますよね?次に、while
を使用する利点は何ですか?
whileループは、常に最初に条件を評価します。
while (condition) {
//gets executed after condition is checked
}
do/whileループは、常にdo{}
最初にブロックしてから、条件を評価します。
do {
//gets executed at least once
} while (condition);
for loopを使用すると、カウンター変数、チェック条件、およびカウンターをすべて1行でインクリメントする方法を開始できます。
for (int x = 0; x < 100; x++) {
//executed until x >= 100
}
結局のところ、それらはすべてループのままですが、実行方法に関してある程度の柔軟性を提供します。
ここでは、物事を明確にするのに役立つ可能性のあるさまざまな種類のループの使用の背後にあるreasoningの素晴らしい説明があります。ありがとう clyfe
for
とwhile
の主な違いは語用論の問題です。通常、反復数がわかっている場合はfor
を使用し、反復数が事前にわからない場合はwhile
コンストラクトを使用します。while
vsdo ... while
問題も実用的であり、2番目は開始時に1回命令を実行し、その後は単純なwhileと同じように動作します。
Forループは簡潔であるため、特に素晴らしいです。このforループのために
for (int x = 0; x < 100; x++) {
//executed until x >= 100
}
whileループとして作成するには、次の手順を実行する必要があります。
int count = 0;
while (count < 100) {
//do stuff
count++;
}
この場合、さらに多くの情報があり、count++;
はロジックで失われる可能性があります。これは、count
がインクリメントされる場所と、ループのロジックの前または後にインクリメントされるべきかどうかによっては、面倒になる可能性があります。 for
ループでは、ループの次の反復の前にカウンター変数が常に増分され、コードにある程度の均一性が追加されます。
完全を期すために、ループ処理を行うときに役立つbreak
およびcontinue
ステートメントについてここで説明することはおそらく意味があります。
breakは、現在のループを即座に終了し、それ以上の反復は実行されません。
//will only run "do stuff" twice
for (int x = 0; x < 100; x++) {
if (x == 2) {
break;
}
//do stuff
}
continueは、現在の反復を終了し、次の反復に進みます。
//will run "do stuff" until x >= 100 except for when x = 2
for (int x = 0; x < 100; x++) {
if (x == 2) {
continue;
}
//do stuff
}
Forループでは、 'continue'は 'for(part1; part2; part3)'の 'part3'式を評価することに注意してください。対照的に、whileループでは、ジャンプしてループ条件を再評価するだけです。
速度とパフォーマンスに強い懸念がある場合、最善のアプローチは、アセンブリレベルでコンパイラによって生成されたコードを検証することです。
たとえば、次のコードは、「do-while」が少し高速であることを示しています。これは、「jmp」命令が「do-while」ループで使用されないためです。
ところで、この特定の例では、最悪の場合は「for」ループによって与えられます。 :))
int main(int argc, char* argv[])
{
int i;
char x[100];
// "FOR" LOOP:
for (i=0; i<100; i++ )
{
x[i] = 0;
}
// "WHILE" LOOP:
i = 0;
while (i<100 )
{
x[i++] = 0;
}
// "DO-WHILE" LOOP:
i = 0;
do
{
x[i++] = 0;
}
while (i<100);
return 0;
}
//「FOR」ループ:
010013C8 mov dword ptr [ebp-0Ch],0
010013CF jmp wmain+3Ah (10013DAh)
for (i=0; i<100; i++ )
{
x[i] = 0;
010013D1 mov eax,dword ptr [ebp-0Ch] <<< UPDATE i
010013D4 add eax,1
010013D7 mov dword ptr [ebp-0Ch],eax
010013DA cmp dword ptr [ebp-0Ch],64h <<< TEST
010013DE jge wmain+4Ah (10013EAh) <<< COND JUMP
010013E0 mov eax,dword ptr [ebp-0Ch] <<< DO THE JOB..
010013E3 mov byte ptr [ebp+eax-78h],0
010013E8 jmp wmain+31h (10013D1h) <<< UNCOND JUMP
}
// "WHILE" LOOP:
i = 0;
010013EA mov dword ptr [ebp-0Ch],0
while (i<100 )
{
x[i++] = 0;
010013F1 cmp dword ptr [ebp-0Ch],64h <<< TEST
010013F5 jge wmain+6Ah (100140Ah) <<< COND JUMP
010013F7 mov eax,dword ptr [ebp-0Ch] <<< DO THE JOB..
010013FA mov byte ptr [ebp+eax-78h],0
010013FF mov ecx,dword ptr [ebp-0Ch] <<< UPDATE i
01001402 add ecx,1
01001405 mov dword ptr [ebp-0Ch],ecx
01001408 jmp wmain+51h (10013F1h) <<< UNCOND JUMP
}
// "DO-WHILE" LOOP:
i = 0;
. 0100140A mov dword ptr [ebp-0Ch],0
do
{
x[i++] = 0;
01001411 mov eax,dword ptr [ebp-0Ch] <<< DO THE JOB..
01001414 mov byte ptr [ebp+eax-78h],0
01001419 mov ecx,dword ptr [ebp-0Ch] <<< UPDATE i
0100141C add ecx,1
0100141F mov dword ptr [ebp-0Ch],ecx
01001422 cmp dword ptr [ebp-0Ch],64h <<< TEST
01001426 jl wmain+71h (1001411h) <<< COND JUMP
}
while (i<100);
読みやすくするために
それらはすべて交換可能です。 1つのタイプを選択して、それ以外は永遠に使用できますが、通常は特定のタスクに便利です。 「なぜスイッチがあるのか、たくさんのifステートメントを使用できる」と言っているようなものです。しかし、変数の値のセットをチェックする一般的なパターンであれば、言語機能があれば便利で読みやすいです。それをするために
特定の反復回数ではなく、条件が真である間にループを実行したい場合、他の誰かがはるかに簡単に理解できます。
while (cond_true)
このようなものより:
for (; cond_true ; )
for
ループは本質的には派手なwhile
ループであることに注意してください。 それらは同じものです。
while <some condition is true> {
// do some stuff
// possibly do something to change the condition
}
for ( some var, <some condition is true>; increment var ) {
}
Forループの利点は、誤って無限ループを実行するのが難しいことです。むしろ、最初のステートメントにループ変数を配置するのが一般的であるため、1つを行うとより明確になります。
while
ループは、標準の増分パターンを実行していない場合により明確になります。例えば:
int x = 1;
while( x != 10 ) {
if ( some condition )
x = 10;
else
x += 5;
}
私が見たwith while
/for
ループのよくある誤解の1つは、効率が異なることです。 While
ループとfor
ループは同等に効率的です。高校のコンピューターの先生が、数値をインクリメントする必要がある場合、forループの方が反復に効率的だと言っていたことを覚えています。そうではありません。
For
ループは単純に 構文的にシュガー化while
ループであり、反復コードの記述を高速化します。
コンパイラーがコードを取得してコンパイルするとき、コンピューターがより低いレベル(アセンブリー)で理解し、実行しやすい形式に変換します。この変換中に、while
構文とfor
構文の微妙な違いが失われ、まったく同じになります。
このようなループを使用する必要があります。これは、ニーズに最も完全に適合しています。例えば:
for(int i = 0; i < 10; i++)
{
print(i);
}
//or
int i = 0;
while(i < 10)
{
print(i);
i++;
}
明らかに、そのような状況では、「for」は「while」よりも良く見えます。また、ループの状態がチェックされる瞬間の前にいくつかの操作を既に実行する必要がある場合は、「do while」を使用する必要があります。
私の悪い英語でごめんなさい)。
for
は、このスキームのインデックスまたはバリアントを使用した固定反復を提案します。
while
およびdo... while
は、毎回チェックする必要がある条件があるときに使用する構造です(インデックスに類似した構造は別として、上記を参照)。条件チェックの最初の実行が実行されるタイミングは異なります。
どちらの構造も使用できますが、ユースケースに応じて長所と短所があります。
Forループは一般的にwhileループよりも多くのマシン命令を生成することに少し前に気付きました。ただし、私の観察結果を反映した例をよく見ると、違いは2つまたは3つの機械語命令であり、あまり考慮する必要はありません。
また、WHILEループの初期化子は、コードにベイクすることで削除できることに注意してください。 g .:
static int intStartWith = 100;
Static修飾子は初期値をコードに焼き付け、(ドラムロール)one MOV命令を保存します。より重要なのは、変数を静的としてマークすると、変数がスタックフレームの外側に移動することです。 MOV命令とそのオペランドは、たとえば整数、ブール値、または文字値(ANSIまたはUnicode)よりも多くのスペースをとるため、変数アライメントも許可します。
ただし、変数が8バイト境界で整列している場合、共通のデフォルト設定、int、bool、またはコードにベイク処理されたTCHARには、MOV命令と同じバイト数がかかります。
彼らは彼らが行う仕事においてすべて同じです。それらのいずれかを使用して同じことを行うことができます。しかし、読みやすさ、使いやすさ、利便性などのために、それらは異なります。
Whileとdo-whileの違いは、whileがループ条件をチェックし、これが真の場合、本体が実行され、条件が再度チェックされることです。 do-whileは本体の実行後に条件をチェックするため、do-whileでは本体が少なくとも1回実行されます。
もちろん、whileループをdo-whileおよびvvとして作成できますが、これには通常、コードの重複が必要です。
Forループ(少なくともC99を考慮)は、増分された変数のスコープを制限するため、whileループよりも優れています。
条件が一部の入力に依存している場合、Do whileループが役立ちます。これらは、3つのループタイプの中でほとんど使用されません。
for and while:while
は初期化も更新ステートメントも必要ないため、見栄えが良く、エレガントになります。 for
には、1つまたは2つまたはすべてのステートメントが欠落している可能性があります。そのため、ループの前に初期化、ループ条件、および「更新」が必要な場合に最も柔軟で明白です。ループ条件(ループの最初でテストされる)のみが必要な場合、while
はよりエレガントです。
for/whileとdo-whileの間:in do-while
条件はループの最後で評価されます。ループを少なくとも1回実行する必要がある場合は、より快適です。
より柔軟です。 FORは、適用される場合により簡潔です。
FORは、次のような何らかのカウンタを持つループに最適です。
for (int n=0; n<max; ++n)
もちろん、他の人が指摘したように、WHILEで同じことを達成できますが、初期化、テスト、および増分は3行に分割されています。ループの本文が大きい場合は、おそらく3行に分けられています。これにより、読者が何をしているのかを見るのが難しくなります。結局のところ、「++ n」はFORの非常に一般的な3番目の要素ですが、それが唯一の可能性ではないことは確かです。 「n + = increment」またはより複雑な式を記述するループを多数作成しました。
もちろん、FORはカウンター以外のものでもうまく機能します。好む
for (int n=getFirstElementFromList(); listHasMoreElements(); n=getNextElementFromList())
等。
しかし、「次回のループ処理」ロジックがより複雑になると、FORが故障します。考慮してください:
initializeList();
while (listHasMoreElements())
{
n=getCurrentElement();
int status=processElement(n);
if (status>0)
{
skipElements(status);
advanceElementPointer();
}
else
{
n=-status;
findElement(n);
}
}
つまり、処理中に発生した条件に応じて進行プロセスが異なる場合、FORステートメントは実用的ではありません。はい、時には十分に複雑な式、三項の?:演算子などを使用して動作させることもできますが、通常はコードを読みやすくするのではなく読みにくくします。
実際には、私のループのほとんどは、ある種の配列または構造をステップスルーしています。その場合、FORループを使用しています。または、データベースからファイルまたは結果セットを読み込んでいます。その場合、WHILEループ( "while(!eof())"またはそのようなもの)を使用します。
do while
の特徴の1つは、完了するまでにセミコロンが必要なことです。多くの場合、マクロの影響を抑制しながら複数のステートメントを一度だけ実行するためにマクロ定義で使用されます。マクロがブロックとして定義されている場合、解析エラーが発生する可能性があります。
do-while
ループ以外はほぼ同じです。 for
ループは、counter
種類の変数がある場合に適しています。それは明らかです。 while
ループは、以下に示すようにフラグがチェックされている場合に意味があります。
while (!done) {
if (some condtion)
done = true;
}
while
およびfor
ステートメントは、両方ともプログラミングのループに使用できます。 while
ループを使用するか、for
ループを使用するかは、プログラマーに依存します。 while
ループの使用に慣れている人もいれば、for
ループを使用している人もいます。
好きなループを使用してください。しかし - do...while
ループは、Cプログラミングでは多少注意が必要です 。
/ * whileループ
5ドル
1チョコレート= 1ドル
while my money is greater than 1 bucks
select chocolate
pay 1 bucks to the shopkeeper
money = money - 1
end
家に来て、買い物中に行くことはできません。なぜなら私のお金= 0ドル* /
#include<stdio.h>
int main(){
int money = 5;
while( money >= 1){
printf("inside the shopk and selecting chocolate\n");
printf("after selecting chocolate paying 1 bucks\n");
money = money - 1 ;
printf("my remaining moeny = %d\n", money);
printf("\n\n");
}
printf("dont have money cant go inside the shop, money = %d", money);
return 0;
}
無限のお金
while( codition ){ // condition will always true ....infinite loop
statement(s)
}
よりよく理解するためにこのビデオをご覧ください https://www.youtube.com/watch?v=eqDv2wxDMJ8&t=25s
/ * forループ
5ドル
for my money is greater than equal to 1 bucks 0 money >= 1
select chocolate
pay 1 bucks to the shopkeeper
money = money - 1 1-1 => 0
end
* /
#include<stdio.h>
int main(){
int money = 5;
for( ; money >= 1; ){ 0>=1 false
printf("select chocolate \n");
printf("paying 1 bucks to the shopkeeper\n");
money = money - 1; 1-1 = 0
printf(" remaining money =%d\n", money);
printf("\n\n");
}
return 0;
}
理解を深めるために、 https://www.youtube.com/watch?v=_vdvyzzp-R4&t=25s をご覧ください。