Cプログラミング入門

第17回 Chapter6 forとwhileで繰り返し(1)

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

for文の使い方

C言語で,たとえば同じ処理を100回繰り返したいという場合には,for文を使って,

for (i = 0; i < 100; i++) {
  printf("i = %d\n", i);
}

のように書きます。ここでは,iという変数の値が0から99まで変化しながらfor文内のループを計100回繰り返します。ループの中にはprintf()が書かれているため,実際に0,1,2...99という値が100行に渡って表示されます。

for文は,一般的には次のような形をしています。

for (初期設定式; 継続条件式; 再設定式) {
  ループで実行する文
}

for文の動作を図6.1に示します。このように,for文はまず初期設定式を実行したあと,継続条件式を実行し,その値がであればループで実行する文を実行し,最後に再設定式を実行したあと再び継続条件式を実行します。この動作が何度も繰り返され,継続条件式の実行結果が偽になるとループを抜け,for文を終了します。なお,継続条件式による条件判断はループの前に行なわれるため,条件によってはループで実行する文が一度も実行されない可能性もあります。

図6.1 for文の動作

図6.1 for文の動作

for文の初期設定式には,文字通り「i = 0」のような,変数を初期化する式を,継続条件式には「i < 100」のような条件判断を行う式を,再設定式には「i++」のように変数の値を次のループのために更新する式を 書くのが普通です。しかし,C言語のfor文はさらに一般化されていて自由度が高く,これらの初期設定式,継続条件式,再設定式に任意の式を書くことができます。

初期設定式,継続条件式,再設定式は,必要がなければ省略することもできます。継続条件式を省略した場合はその条件は常に真とみなされます。

なお,ループで実行する文がひとつしかない場合,文法的には{ }をつけて複文にする必要はありませんが,ソースの可読性を高めるため,{ }を省略しない方がよいでしょう。

1から100まで足してみる

for文を使って,整数値を1から100まで加える計算をするプログラムをリスト6.1に示します。このプログラムでは変数iの値が1から100まで変化しながらループを回り,ループの中ではsumという変数にiの値を加えています。

sum.cをコンパイルして実行すると,図6.2の実行例のとおり,正しく5050という値が表示されます。

リスト6.1 sum.c

#include <stdio.h>

int
main()
{
  int i, sum;

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

図6.2 リスト6.1(sum.c)の実行例

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

基本的なwhile文の使い方

while文は,

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

という形をした文で,継続条件式の値が真である限り,ループを繰り返します。while文の動作を図6.3に示します。なお,while文ではfor文とは違って,継続条件式を省略することはできません。

図6.3 while文の動作

図6.3 while文の動作

while文は,for文から初期設定式と再設定式を取り除いたものと同じです。

たとえば,

while (i < 100)

と書いたのは,

for (; i < 100;)

と書いたのと同じになります。

このように,for文はwhile文を兼ねており,while文はfor文の特別な場合であると考えていいでしょう。ただし,while文の場合は継続条件式を省略することはできません。

たとえば,前述のsum.c(リスト6.1)の中のfor文は,リスト6.2のようにwhileで書くこともできます。もちろん,図6.4のとおり実行結果も同じです。

リスト6.2 sum_while.c

#include <stdio.h>

int
main()
{
  int i, sum;

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

図6.4 リスト6.2(sum_while.c)の実行例

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

なお,while文のループの中に後述のcontinue文がある場合,while文とfor文の動作に少し違いが発生します。sum.cとsum_while.cの例では,ループ中の際にi++が実行されるかどうかが違い,while文の場合はcontinueするとi++が実行されません。

このように,同じプログラムがfor文を使ってもwhile文を使っても書けるわけですが,for文を使うかwhile文を使うかは,ソースの可読性の問題などを考慮して決めればよいでしょう。通常は,ループ変数をインクリメント(またはデクリメント)しながら繰り返す場合はfor文を,とくにループ変数がなく,ある一定条件になるまでループを繰り返すという意味合いが強い場合はwhile文にすればよいでしょう。

著者プロフィール

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

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

著書

コメント

  • リスト6.1 sum.cに付いて

    これが不思議なんですが、このコードをKNOPPIX/Math2008上で

    gcc -O2 -o sum sum.c

    としてコンパイルして

    sum

    として実行すると、どういうわけか無限ループに陥って止まらなくなります。
    恐らくgccのバグなのかもしれませんが・・・・・・。

    なお、KNOPPIX/Math2008上のgccのヴァージョンは、

    knoppix@Knoppix:~$ gcc -v
    Using built-in specs.
    Target: i486-linux-gnu
    Configured with: ../src/configure -v --enable-languages=c,c++,fortran,objc,obj-c++,treelang --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --program-suffix=-4.1 --enable-__cxa_atexit --enable-clocale=gnu --enable-libstdcxx-debug --enable-mpfr --with-tune=i686 --enable-checking=release i486-linux-gnu
    Thread model: posix
    gcc version 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)

    だそうです。
    なお、while版の方はうまく動きます。

    Commented : #1  cametan (2008/08/16, 13:30)

コメントの記入