問: 与えられた整数の配列 a[4] の要素の値の総和を表示するプログラムを示せ。ただし、初期値は適当に設定してよい。
考え方: 「sum = a[0] + a[1] + a[2] + a[3];」のような式では大きい配列に使いづらいので 「{sum = sum + a[i];}」の繰り返しで計算する。
#include <stdio.h> |
#include <stdio.h> |
☆ 「<* i=1 to 3 *>{sum = sum + a[i];}」は「
<* 順に実行 *>{
sum = sum + a[1];
sum = sum + a[2];
sum = sum + a[3];
}
」の意味。書きかえると「
<* 順に実行 *>{
i = 1; sum = sum + a[i];
i = 2; sum = sum + a[i];
i = 3; sum = sum + a[i];
}
」。すなわち 1 ≦ i ≦ 3 の範囲で「sum = sum + a[i];」を繰り返す。
☆ 「i = i+1」より「i++」を使うことが多い。
★ 「for(i = 1; i < 4; i = i+1){sum = sum + a[i];}」は「
i = 1;
while(i < 4){
sum = sum + a[i];
i = i+1;
}
」と同じ。したがって 「for(i = 1; i <= 3; i = i+1)」等でもよい。
擬似コード「<* i=m to n *>」に関する補足:
「<* i=m to n *>」 は Algol の 「for i := m step 1 until n do」 に対応する基本的な繰り返し構造で、BASIC では「FOR I = 1 TO 3」 と書く(末尾に「NEXT」)。 K&R2, p.74 でも 「for(i = 0; i < n; i++)」 を “これは Fortran の DO ループや、Pascal の for と同様な、配列の最初の n 要素を処理するための C の慣用句である” と書かれている。 しかし、一般形 「for(式1; 式2; 式3){文}」 は
「式1; while(式2){文 式3;}」
すなわち
(1) 「式1;」を実行。 (2) 「式2」 でなければ (5) へジャンプ。 (3) 「文」「式3;」 を実行。 (4) (2) へジャンプ。 (5) 次へ進む。 |
と等価であり、処理の流れを見にくい。 「for(i = 0; i < n; i++)」 を使うときは初期化 「i = 0;」 が終了した直後は 「i < n」 であるから、このような場合は
「式1; do{文 式3;}while(式2);」
すなわち
(1) 「式1;」を実行。 (2) 「文」「式3;」 を実行。 (3) 「式2」 でなければ (2) へジャンプ。 |
に対応させると分かり易くなる。例えば 「<* i=1 to 3 *>{sum = sum + a[i];}」 は
「i = 1; do{sum = sum + a[i]; i++;}while(++i <= 3);」
★ コンマ演算子を使えば 「式1; do{文}while(式3,式2);」 (K&R2, p.258)。
★ 一般形の別表現は 「式1; if(式2)do{文 式3;}while(式2);」
break 文を使えば 「式1; while(1){if(式2) break; 文 式3;}」
問: 与えられた文字の配列 s[80] に書かれている文字列の長さを表示するプログラムを示せ。ただし、初期値は適当に設定してよい。
考え方: 文字列の最後に '\0' があるから、これを s[0]、s[1]、・・・を順に調べ、「s[k] == '\0'」となる k が見つかれば長さは k 。
#include <stdio.h> |
#include <stdio.h> |
☆ <*「s[k] != '\0'」の間 *>{k = k+1;}は <*
(1) 「s[k] != '\0'」でなければ(3)にジャンプ。
(2) 「k = k+1;」を実行して(1)に戻る。
(3) 次へ進む。
*> を意味する。この場合の“次”は「printf("長さは %d\n", k);」
★ 「while(s[k] != '\0')」は「for(;s[k] != '\0';)」と同じ。
★ 「while(s[k] != '\0'){k = k+1;}」は「while(s[k++]);」と同じ。
問: 整数の配列 m[100] にテストの点数をキー入力して、平均点を表示するプログラムを示せ。ただし、テストの答案数は100以下で、答案がなくなったときは -1 をキー入力することを前提にする。
考え方: キー入力の値が繰り返しの有無を定めるので do-while 文が適している。
#include <stdio.h> |
#include <stdio.h> |
☆ 「{・・・}<*「m[k] >= 0」の間 *>;」は「m[k] >= 0」である間は「{・・・}」を繰り返す。
☆ 「k++;」は「k = k + 1;」と、「k--;」は「k = k - 1;」と同じ。
★ 「if(k == 0){return 0;}」は(データ 0 個の)例外処理。
★ 「x = 0; k = 0;」は「x = k = 0;」でもよい。
★ 「do{scanf("%d", &m[k]); x = x + m[k]; k++;}while(m[k] >= 0);」は「
scanf("%d", &m[k]);
while(m[k] >= 0){x = x + m[k]; k++; scanf("%d", &m[k]);}
」や、break 文を用いた「
while(1){
scanf("%d", &m[k]); x = x + m[k]; k++;
if(m[k] < 0){break;}
}
」と同じ。
※コメント投稿者のブログIDはブログ作成者のみに通知されます