サーチ…


構文

  • / *すべてのバージョン* /
  • for([expression]; [expression]; [expression])one_statement
  • for([expression]; [expression]; [expression]){ゼロまたは複数の文}
  • 一方、(式)one_statement
  • while(式){0個以上の文}
  • while(expression)while one_statementを実行します。
  • while(expression)while {1つ以上の文}を実行します。
  • //上記のフォームに加えてC99以降
  • for(宣言; [式]; [式])one_statement;
  • for(宣言; [式]; [式]){ゼロまたは複数の文}

備考

反復ステートメント/ループは2つのカテゴリに分類されます。

  • head-controlled iteration文/ループ
  • フットコントロール反復ステートメント/ループ

ヘッド制御反復ステートメント/ループ

for ([<expression>]; [<expression>]; [<expression>]) <statement>
while (<expression>) <statement>
C99
for ([declaration expression]; [expression] [; [expression]]) statement

フットコントロールのイテレーションステートメント/ループ

do <statement> while (<expression>);

ループの場合

何度も繰り返してコードブロックを実行するには、ループが画像に入ります。 forループは、コードブロックが一定回数実行されるときに使用されます。例えば、サイズn配列をユーザ入力で満たすには、 scanf()n回実行する必要があります。

C99
#include <stddef.h>          // for size_t

int array[10];               // array of 10 int

for (size_t i = 0; i < 10; i++)    // i starts at 0 and finishes with 9
{
   scanf("%d", &array[i]);
}

このように、 scanf()関数呼び出しはn回(この例では10回)実行されますが、1回だけ書き込まれます。

ここで、変数iはループインデックスであり、提示されたものとして最もよく宣言される。 size_t型の型 )は、データオブジェクトを数えたりループしたりするすべてのものに使用する必要があります。

for内部で変数を宣言するこの方法は、C99標準に更新されたコンパイラでのみ使用できます。なんらかの理由で古いコンパイラに悩まされている場合は、 forループの前にループインデックスを宣言することができます:

C99
#include <stddef.h>        /* for size_t */
size_t i;
int array[10];             /* array of 10 int */

for (i = 0; i < 10; i++)       /* i starts at 0 and finishes at 9 */
{
   scanf("%d", &array[i]);
}

whileループ

whileループは、条件が真である間にコードを実行するために使用されます。 whileループは、コードのブロックが可変回数実行されるときに使用されます。たとえば、表示されているコードは、ユーザーが0数字を挿入している限り、ユーザー入力を取得します。ユーザーが0挿入した場合、while条件は真ではなくなり、実行はループを終了し、後続のコードに続きます。

int num = 1;

while (num != 0)
{
    scanf("%d", &num);
}

Do-Whileループ

forループとwhileループとは異なり、 do-whileループはループの最後に条件の真偽をチェックします。つまり、 doブロックは一度実行され、ブロックの最下部のwhileの状態をチェックします。つまり、 do-whileループは常に少なくとも1回実行されます。

たとえば、このdo-whileループは、これらの値の合計が50以上になるまで、ユーザーからの数値を取得します。

int num, sum;
num = sum = 0;

do 
{
  scanf("%d", &num);
  sum += num;

} while (sum < 50);

do-whileループは、ほとんどのプログラミングスタイルで比較的まれです。

forループにおける制御の構造と流れ

for ([declaration-or-expression]; [expression2]; [expression3])
{
    /* body of the loop */
}

forループでは、ループ条件に3つの式があり、すべてオプションです。

  • 最初の式declaration-or-expressionは、ループを初期化します。ループの開始時に1回だけ実行されます。
C99

これは、ループ変数の宣言と初期化、または一般的な式のいずれかです。宣言の場合、宣言された変数のスコープはforステートメントによって制限されます。

C99

Cの歴史的なバージョンではここで式のみが許され、ループ変数の宣言はfor前に置く必要がありfor

  • 2番目の式expression2テスト条件です。初期化後に最初に実行されます。条件がtrue場合、コントロールはループの本体に入ります。そうでない場合は、ループの最後にループの本体の外側に移動します。その後、bodyとupdateステートメントが実行されるたびにこの条件がチェックされます。 true場合、コントロールはループの本体の先頭に戻ります。この条件は通常、ループの本体が実行される回数をチェックすることを意図しています。これはループを終了させる主な方法です。もう1つはジャンプ文を使用する方法です。
  • 3番目の式expression3は、 更新ステートメントです。ループの本体が実行されるたびに実行されます。これは、ループ本体が実行された回数を保持する変数をインクリメントするためによく使用され、この変数はイテレータと呼ばれます

ループ本体の各実行インスタンスは反復と呼ばれます

例:

C99
for(int i = 0; i < 10 ; i++)
{
    printf("%d", i);
}

出力は次のとおりです。

0123456789

上記の例では、最初にi = 0が実行され、 i初期化されます。次に、条件i < 10がチェックされ、これはtrueと評価される。コントロールはループの本体に入り、 iの値が出力されます。その後、制御へ移行しi++の値更新、 i続いて0から1に、条件が再度チェックされ、処理が続行されます。これは、 iの値が10になるまで続きます。次に、条件i < 10false評価し、その後、コントロールはループから移動します。

無限ループ

ループが無限ループと呼ばれるのは、制御が入力されてもループの本体から離れることはないということです。これは、ループのテスト条件がfalse評価されない場合に発生しfalse

例:

C99
for (int i = 0; i >= 0; )
{
    /* body of the loop where i is not changed*/
}

上記の例では、イテレータである変数iは0に初期化されていtrue 。テスト条件は最初はtrueです。しかし、 iは体のどこでも変更されず、更新式は空です。したがって、 iは0のままであり、テスト条件は決してfalseに評価されることはなく、無限ループにつながります。

ジャンプ文がないと仮定すると、無限ループが形成される別の方法は、明示的に条件を真に保つことです:

while (true)
{
    /* body of the loop */
}

forループでは、条件文はオプションです。この場合、条件が常にtrue無限ループにつながる、意味をなさない。

for (;;)
{
    /* body of the loop */
}

しかし、場合によっては、 breakなどのジャンプ文を使用してループを終了する意図で、条件を意図的にtrueに保つことができます。

while (true)
{
    /* statements */
    if (condition)
    {
         /* more statements */
         break;
    }
}

ループアンロールとダフのデバイス

時には、ストレートフォワードループをループ本体に完全に含めることはできません。これは、ループがいくつかのステートメントBによってプライムされる必要があるからです。次に、繰り返しがいくつかのステートメントAで始まり、ループの前に再びBが続きます。

do_B();
while (condition) {
    do_A();
    do_B();
}

コード内で二回Bを繰り返すことで潜在的なカット/ペーストの問題を回避するには、 ダフのデバイスがの途中からループを開始するために適用され得るwhile使用して、体switch文をし、行動を通って落下します。

switch (true) while (condition) {
case false: do_A(); /* FALL THROUGH */
default:    do_B(); /* FALL THROUGH */
}

ダフのデバイスは、実際にはループアンローリングを実装するために発明されました。メモリブロックにマスクを適用すると想像してくださいnは正の値を持つ符号付き整数型です。

do {
    *ptr++ ^= mask;
} while (--n > 0);

nが常に4で割り切れる場合は、簡単にこれを展開することができます:

do {
    *ptr++ ^= mask;
    *ptr++ ^= mask;
    *ptr++ ^= mask;
    *ptr++ ^= mask;
} while ((n -= 4) > 0);

しかし、Duffのデバイスでは、 nが4で割り切れない場合、コードはループの途中で正しい場所にジャンプするこのアンローリングイディオムに従うことができます。

switch (n % 4) do {
case 0: *ptr++ ^= mask; /* FALL THROUGH */
case 3: *ptr++ ^= mask; /* FALL THROUGH */
case 2: *ptr++ ^= mask; /* FALL THROUGH */
case 1: *ptr++ ^= mask; /* FALL THROUGH */
} while ((n -= 4) > 0);

コンパイラの最適化エンジンはプログラマのためにループを展開することができるので、この種の手動アンロールは最新のコンパイラではほとんど必要ありません。



Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow