授業/C言語基礎/for文 のバックアップ差分(No.7)


  • 追加された行はこの色です。
  • 削除された行はこの色です。
*同じ処理を繰り返し行う [#p95b0769]

コンピューターは、同じ処理を繰り返し行うことが得意です。

次のようなプログラムを考えてみましょう。
  Hello World!と10回画面に表示する

これをそのままプログラムにすると、次のようになります。
#geshi(c){{
  printf("Hello World!\n");    // 1
  printf("Hello World!\n");    // 2
  printf("Hello World!\n");    // 3
  printf("Hello World!\n");    // 4
  printf("Hello World!\n");    // 5
  printf("Hello World!\n");    // 6
  printf("Hello World!\n");    // 7
  printf("Hello World!\n");    // 8
  printf("Hello World!\n");    // 9
  printf("Hello World!\n");    // 10
}}
全く同じ命令が10回繰り返されています。
(コメント部分はコンパイル時に無視されます。)

''for文''は、このような同じ処理を繰り返し行うことができます。

for文は、次の形をしています。
#geshi(c){{
  int i;
  for(i = 1; i <= 繰り返し回数; i++) {
    処理
  }
}}
ここで、''++'' は''インクリメント演算子''です。
後で詳しく説明します。

for文を使って上のプログラムを書くと、次のようになります(プログラム1)。
#geshi(c){{
  int i
  int i;
  for (i = 1; i <= 10; i++) {
    printf("Hello World!\n");
  }
}}

これを実行すると、次のようになります。
#geshi(sh){{
luna% a.out
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
}}

**演習1 [#rce0b366]
プログラム1を作成し、実行結果を確認せよ。


*カウント変数 [#ke44bbbd]

for文で使われている変数 i は、繰り返し回数をカウントするのに使われています。
繰り返し回数をカウントしているので、''カウント変数''と呼ばれます。
カウント変数の名前は、i でなくても構いません。

上のプログラムに、変数 i の値を出力する命令を追加します(プログラム2)。
#geshi(c){{
  int i;
  for (i = 1; i <= 10; i++) {
    printf("%d\n", i);
    printf("Hello World!\n");
  }
}}

これを実行すると、次のようになります。
#geshi(sh){{
luna% a.out
1
Hello World!
2
Hello World!
3
Hello World!
4
Hello World!
5
Hello World!
6
Hello World!
7
Hello World!
8
Hello World!
9
Hello World!
10
Hello World!
}}




**演習2 [#tddc3255]
プログラム1をプログラム2に変更し、実行結果を確認せよ。





*増分・減分演算子 [#b42c48af]

for文の中で使われている ''++'' という演算子は、''増分演算子''(インクリメント演算子)といい、カウント変数 i の値を1増やす演算子です。

増分演算子と同じ仲間に、変数の値を1減らす''減分演算子''(デクリメント演算子)があります。
|優先順位|演算子|使用例|意味|h
|2|++|i++|iの値を1増やす|
|~|~|++i|~|
|~|&minus;&minus;|i&minus;&minus;|iの値を1減らす|
|~|~|&minus;&minus;i|~|
演算子が変数の前についている場合(前置)と変数の後についている場合(後置)では意味が違いますが、後日詳しく勉強します。



*for文 [#m3ff44a2]

上では、for文の形を次のように説明しました。
#geshi(c){{
  int i;
  for(i = 1; i <= 繰り返し回数; i++) {
    処理
  }
}}

正確に説明すると、for文は次の形をしています。
#geshi(c){{
  for (初期化; 繰り返し条件; 更新処理) {
    処理
  }
}}
if文と同じように、for文の波括弧 { } に含まれる命令文が0または1個のとき、この波括弧を省略することができます。

for文は、次のように実行されます。
+「初期化」を行う
+「繰り返し条件」を評価する
--条件を満たしていれば、波括弧 { } の中の「処理」を行い、最後に「更新処理」を行う
--そうでなければ、for文の次の処理に移る
+2へ戻る

したがって、カウント関数は1からでなく、0から始めることもできます。
また、カウント関数を1ずつ増やすのではなく、2ずつ増やしたり、1ずつ減らすこともできます。

たとえば、10から0までカウントダウンするプログラムは、次のようになります(プログラム3)。
#geshi(c){{
  int i;
  for (i = 10; i >= 0; i--) {
    printf("%d\n", i);
    sleep(1);
  }
}}

**演習3 [#me0ecdb9]
プログラム3を作成し、実行結果を確認せよ。


**無限ループと強制停止 [#afb3951c]

for文は、条件を満たしている間繰り返し続けますので、条件を満たさないことがないと無限に繰り返しを続けます。
これを''無限ループ''といいます。

たとえば、次のプログラムについて考えてみます(プログラム4)。
#geshi(c){{
  int i;
  for (i = 1; i = 10; i++) {
    printf("%d\n", i);
    printf("Hallo World!\n");
  }
}}
繰り返し条件の演算子を間違えて、代入演算子にしてしまっています。

繰り返し条件を評価すると、カウント変数に10が代入されます。
このとき、結果が0でないので、条件を満たしていると判断され、波括弧の中の処理と更新処理がおこなわれます。
更新処理によってカウント変数は11になりますが、繰り返し条件を評価すると、カウント変数に10が代入されるため、このfor文が停止することはありません。

このようなとき、''コントロール・キー''を押しながら''C''キーを押し、プログラムの実行を強制的に停止させます。
コントロール・キーを押しながらCキーを押す操作を、''Ctrl+C''と書くことがあります。


**演習4 [#ha668b44]
プログラム2をプログラム4に変更し、実行して強制停止せよ。


*合計を求める [#c9a294dc]

繰り返し処理を用いてよく行われることの一つが、合計を求めることです。

1から100までの整数の和を求めることを考えてみます。

そのままプログラムにすると次のようになります。
#geshi(c){{
  int sum = 1 + 2 + 3 + 4 + 5 + ... + 99 + 100;
  printf("%d\n", sum);
}}
もちろん、...の部分も省略せずに書かなければなりませんが、ここでは省略してあります。

この処理は、2を足す、3を足す、4を足す ... という足し算の繰り返しだと考えることができます。
この処理は、2を加える、3を加える、4を加える ... という加算の繰り返しだと考えることができます。

したがって、加える数をカウント変数とすると、次のようなプログラムにできます。
そこで、この処理を、次のように同じ命令文の繰り返しの形に直します。
#geshi(c){{
  int sum = 1;
  sum = sum + 2;
  sum = sum + 3;
  sum = sum + 4;
  sum = sum + 5;
  ...
  sum = sum + 99;
  sum = sum + 100;
  printf("%d\n", sum);
}}

ここで、
#geshi(c){{
  sum = sum + 2;
}}
は、右辺の計算をしてから代入が行われるため、変数sumの値に2を加えた結果を変数 sum に代入します。
つまり、変数 sum の値に2を加えます。

加える数をカウント変数 i で表すと、繰り返し行われている加算の処理はすべて
#geshi(c){{
  sum = sum + i;
}}
という形で書くことができます。

したがって、加える数をカウント変数とし、カウント変数を2に初期化して100まで繰り返すと、次のようなfor文を使ったプログラムにできます(プログラム5)。
#geshi(c){{
  int i, sum = 1;
  for (i = 2; i <= 100; i++) {
    sum = sum + i;
  }
  printf("%d\n", sum);
}}
変数sumが合計を表していて、今までの合計に2を加えて新しい合計とする、今までの合計に3を加えて新しい合計とする、...と繰り返しています。

これでも間違いではありませんが、普通は、合計を表す変数の値を0に初期化して、最初の数も加えていると考えます。

つまり、
#geshi(c){{
  int sum = 0 + 1 + 2 + 3 + ... + 99 + 100;
  printf("%d\n", sum);
}}
と変形して、次のようなプログラムにします(プログラム6)。
#geshi(c){{
  int i, sum = 0;
  for (i = 1; i <= 100; i++) {
    sum = sum + i;
  }
  printf("%d\n", sum);
}}

これだと、合計を求める範囲が変わったときに、カウント変数の初期値と繰り返し条件のところだけを変えるだけで済みます。
(プログラム5は、sumの初期値も変えなければなりません。)

**演習5 [#v07f34ae]
プログラム6を作成し、実行結果を確認せよ。



*複合代入演算子 [#oacd17e7]

合計を求めるプログラムで出てきたような、変数の値にある値を加えて、その結果をその変数に代入するという処理はよく行われます。
#geshi(c){{
  sum = sum + i
}}

そこで、算術演算と代入を同時に行うための演算子が用意されていて、これを''複合代入演算子''といいます。

上の処理の場合、加算用の複合代入演算子 ''+='' を使って、次のように書くことができます。
#geshi(c){{
  sum += i;
}}

したがって、プログラム6は、次のように書くことができます(プログラム7)。
#geshi(c){{
  int i, sum = 0;
  for (i = 1; i <= 100; i++) {
    sum += i;
  }
  printf("%d\n", sum);
}}


算術演算の複合代入演算子には、次のようなものがあります。
|優先順位|演算子|使用例|意味|h
|15|+=|a += b|aとbの和をaに代入する(加算代入)|
|~|&minus;=|a &minus;= b|aとbの差をaに代入する(減算代入)|
|~|*=|a *= b|aとbの積をaに代入する(乗算代入)|
|~|/=|a /= b|aをbで割ったときの商をaに代入する(除算代入)|
剰余算の複合代入演算子はありません。


**演習6 [#dbd5c59c]
プログラム6をプログラム7に変更し、実行結果を確認せよ。


*for文のネスト [#l153c748]

for文の中にfor文を入れることを''ネスト''(入れ子構造)といいます。

for文をネストするとき、外側のfor文と内側のfor文では異なるカウント変数を使用します(プログラム8)。
#geshi(c){{
  int i, j;
  for (i = 1; i <= 5; i++) {
    for (j = 1; j <= i; j++) {
      printf("*");
    }
    pinrtf("\n");
  }
}}
外側のfor文のカウント変数が i、内側のfor文のカウント変数が j です。

内側のfor文の繰り返し回数が、外側のfor文のカウント変数の値になっています。
つまり、外側のfor文は「内側のfor文と改行だけを出力するprintf文」を5回繰り返し実行し、内側のfor文は「* を出力するpriftf文」を外側のカウント変数の回数だけ繰り返し実行します。

このプログラムを実行すると、次のようになります。
#geshi(sh){{
luna% a.out
*
**
***
****
*****
}}


**演習7 [#ubbd4d1e]
プログラム8を作成し、実行結果を確認せよ。

トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS