Cプログラミング入門

第18回 Chapter6 forとwhileで繰り返し(2)

この記事を読むのに必要な時間:およそ 2.5 分

for文で無限ループ

前述のとおり,for文の初期設定式,継続条件式,再設定式は任意に省略可能です。そこで,これらをすべて省略すると無限ループが実現できます。

  for (;;) {
    ループで実行する文
  }

無限ループはwhile文を使っても実現できますが,while文の場合は継続条件式を省略できないため,真の値として1を使って,while (1)と書く必要があります。

無限ループでは通常,ループ中にif文とともにbreak文やreturn文などを置いて,一定の条件のもとでループを終了するようにします。

do while文もある

さらに,C言語には次のようなdo while文もあります。do while文のwhileには右側にセミコロン(;)が要るので注意してください。

  do {
    ループで実行する文
  } while (継続条件式);

for文やwhile文では,条件継続式による判定がループ内部を実行する前に行われるため,これではループが一度も実行されない可能性があります。do while文は,継続条件式の判定をループ内部の実行のあとに行います。この結果,ループ内部の文は最低1回は実行されるようになります。

do while文とwhile文とは,継続条件式による判定が行われるタイミングのみが異なります。このdo while文は,ループ内部の文を実行してみないと継続条件を判定できないようなプログラムを記述するのに使えます。

do while文の動作を図6.7に示します。

図6.7 do while文の動作

図6.7  do while文の動作

前述のsum.cまたはsum_while.cを,do whileを使って書き直すとリスト6.6のようになります。図6.8のように,実行結果もこれまでと同じです。

リスト6.6 sum_do_while.c

#include <stdio.h>

int
main()
{
  int i, sum;

  sum = 0;
  i = 1;
  do {
    sum += i;
    i++;
  } while (i <= 100);
  printf("sum = %d\n", sum);
  return 0;
}

図6.8 リスト6.6(sum_do_while.c)の実行例

$ gcc -O2 -o sum_do_while sum_do_while.c
$ ./sum_do_while
sum = 5050
$

for文の1回目は無駄にならない

たとえば,次のようなfor文を考えてみてください。

  for (i = 0; i < 100; i++) {
    /* ループ */
  }

このプログラムの実行順を詳しく考えると,変数iにまず0が代入された直後にも「i < 100」という条件判断が行われてしまうということに気づくでしょう。この場合,iには0という値を代入したばかりなので,⁠i < 100」という条件判断をしなくても,それが真であることは明らかです。しかし,for文を使う限り,この無駄に思える条件判断がループの前に必ず行なわれてしまいます。

この無駄な条件判断をなくしてプログラムを高速化するには,do while文を使って,

  i = 0;
  do {
    /* ループ */
  } while (++i < 100);

とすればよいと考えられます。しかし,こう書くとやはりプログラムが読みにくくなってしまいます。実際には,多くのコンパイラでは,⁠for (i = 0; i < 100; i++)」のような明らかに1回目の条件判断が無駄であると判定できる場合は,1回目の条件判断をしないという最適化を行うようになっています。

このため,プログラマとしてはこの無駄を気にせずに,安心して「for (i = 0; i < 100; i++)」と書けばよいということになります。

著者プロフィール

山森丈範(やまもりたけのり)

「C言語はアセンブラを触っているうちに自然に覚えてしまった」というプログラマ。C言語とのかかわり上,OSは専らUNIXを使用。C言語のプログラムでは,いつもLinux/FreeBSD/Solarisすべてで動くことを気に留めている。C言語と同様に移植性の高いシェルスクリプトにも思い入れが深く,著書に『シェルスクリプト基本リファレンス』がある。

著書