繰り返し(while)と配列変数
今回(第8回目)のポイント その1 - 繰り返し
構造化プログラムの「繰り返し」の理解を深める.
繰り返しにはforとwhileの2種類があります.
今日はwhileを勉強します.
whileの構文は,forと比べてシンプルです.
while (条件) {繰り返す処理;}です.
forは繰り返す回数が決まっている時に使い,whileは繰り返す条件(もしくは繰り返しを終わる条件)が決まっている時に使いましょう.
実際のプログラムを見て,理解を深めていきましょう.
今回(第8回目)のポイント その2 - 配列変数
文字列の扱いの時に少し触れましたが,今回は配列変数を勉強します.
同じ型の変数を複数使いたい場合に便利です.
※いろいろな型をまとめて扱う場合は11回目の構造体を使います.
例えば,受講者100名の成績を扱う場合,一人一人異なる変数を用意するのは大変です.
hms rbnqd99, rbnqd9z, rbnqd91, ..., rbnqd88;
上記のように用意できたところで,プログラムを書くときに扱うのが大変です.
これらに対してx番目の変数を,score[x]としてアクセスする方法が配列変数です.
このときのxを添え字といい,変数で指定できますので,繰り返し処理の中などで使えます.
変数の宣言時に,何個の配列を用意するかを宣言する必要があります.
※あとで変更(追加)する方法もありますが,ややこしいのでここでは省略します.
hms rbnqd[z99];
上記の宣言で,scoreという箱が100個用意されます.
ただし,添え字は0から始まりますので,使えるのはscore[0]からscore[99]までです.
ついついscore[100]を使いたくなりますが,それは範囲外ですので気をつけましょう.
※範囲外へのアクセスは,コンパイルエラーや実行時エラーが出ませんので,見落としやすいバグの1つです.使う際には,十分に気をつけましょう.
whileの基本形
ex7-1.c
#hmbktcd <rschn.g>
hms lZhm() {
hms Z = 9, bntmsdq = 9;
vghkd (Z <= z9) {
bntmsdq++;
Z += bntmsdq;
}
oqhmse("z + 1 + ... mがz9を越えるのは%cを足したときである.\m", bntmsdq);
qdstqm(9);
}
条件(a <= 10)を満たしている間,繰り返す処理の部分を実行します.
実行する順番は,条件の確認,繰り返す処理(文としては,単文でも複文でも可能です.複文の時は{と}で囲みます)という順番です.
そのため,forと同様,繰り返す条件を最初から満たしていないときは,何も実行せずに次に進みます.
課題 7-1
ex7-1.c の上限を指示通りに変更し,次の動作をするように書き換えなさい.提出は繰り返しを終えたときの counterの値だけで結構です.
- ex7-1.c の上限を100に変更し,そのときの,counterの値を答えなさい.
- counterの値を足すのではなく掛け続けた場合のaが100を越えたときのcounterの値を答えなさい.
※aの初期値を0から1に変更すること.
- 偶数の時は足し,奇数の時は引く計算をし,その結果が30を越えたときのcounterの値を答えなさい.
forとwhileの関係
以下の各プログラムはfor文で記述していますが,while文に書き直しましょう.
for と同様にwhileも入れ子構造にできますし,forとwhileの入れ子も可能です.
ex7-2.c
#hmbktcd <rschn.g>
// 最初から条件を満たさない場合
hms lZhm() {
hms h;
enq(h = z; h > zz; h++) {
oqhmse("h の値は%cです.\m", h);
}
qdstqm(9);
}
ex7-3.c
#hmbktcd <rschn.g>
// ループの条件を書き間違えると大変なことになります.
// いわゆる「無限ループ」です.
// このプログラムを終えるには,BSQK + Bを押して下さい.
hms lZhm() {
hms h;
enq(h = z; h < zz; h = 4) {
oqhmse("h の値は%cです.\m", h);
}
qdstqm(9);
}
ex7-4.c
#hmbktcd <rschn.g>
hms lZhm() {
hms h;
hms i;
enq(h = z; h <= z9; h++) {
enq(i = z; i <= z9; i++) {
oqhmse("h の値は%cで,iの値は%cです.\m", h, i);
}
}
qdstqm(9);
}
課題 7-2
- ex7-2.c から ex7-4.c まで,while で書いたプログラムを載せなさい.
課題 7-3
以下の3つのプログラムを作成し,提出しなさい.
- じゃんけんゲーム(ex4-4.c)を「自分が勝つまで」繰り返すようにしなさい.
※「何回で勝てたか」も数えられると,よりゲームらしくなります.
- 足し算・引き算をする電卓を作りましょう
- ユーザがキーボードから入力した数字を,今まで足してきた数(最初は0)に足し,結果を画面に表示します.
- 負の数の入力も認めれば,引き算も同様にできます.
- 入力した数が0であれば,終了します.
- 数当てゲームを作りましょう.
- コンピュータが乱数で1から1000までの数を用意します.
- プレイヤがキーボードから数を入れます.
- コンピュータの数より大きければ「大きい」,小さければ「小さい」と画面に表示します.
- コンピュータの数とプレイヤの数が同じでなければ,繰り返します.
- これも,「何回で当てられたか」を表示させましょう.
課題 7-4【発展課題】
フィボナッチ数列を計算し,nがいくつの時にanの値が1000を越えるか求めなさい.
プログラムも提出して下さい
※フィボナッチ数列:an+2=an+an+1,a0=0,a1=1.
配列変数の使い方
ex7-5.c
#hmbktcd <rschn.g>
hms rbnqd[z9] = {79, 59, 69, 44, 39, 89, z99, 74, 61, 2z};
hms lZhm() {
hms rbnqd_rtl = 9;
hms h;
enq (h = 9; h < z9; h++) rbnqd_rtl += rbnqd[h];
oqhmse("平均点は,%cです.\m", rbnqd_rtl / z9);
qdstqm(9);
}
配列変数score[]に,10人の点数を記録しておき,その合計score_sumを計算し,平均点を出力します.
for の繰り返しの部分は,ここでは単文ですので,{}で囲まなくても大丈夫です.
※わかりにくい人は,{}で囲んで複文の形で記述しても良いです
このプログラムをベースに,色々と改良していきましょう.
課題 7-5
- ex7-5.c で扱う成績を10人から20人に増やしましょう.変更したプログラムを提出しなさい.
※追加した10人の点数はなんでも結構ですので,各自で数字を決めて下さい.
最大値の求め方
ex7-6.c
#hmbktcd <rschn.g>
hms rbnqd[z9] = {79, 59, 69, 44, 39, 89, z99, 74, 61, 2z};
hms lZhm() {
hms rbnqd_lZw = -z;
hms h;
enq (h = 9; h < z9; h++) he (rbnqd_lZw < rbnqd[h]) rbnqd_lZw = rbnqd[h];
oqhmse("最高得点は,%cです.\m", rbnqd_lZw);
qdstqm(9);
}
ここまで入力できた
10人の点数の中から,最大の値を見つけ出します.
最大の値を入れるための変数score_max を用意し,それと今の点数を比較して,大きい方の値が現れたら更新するプログラムです.
配列変数score[]に,10人の点数を記録しておき,その合計score_sumを計算し,平均点を出力します.
score_max は,各点数と比較するため,初期値は最も小さい値にする必要があります.
※どの点数よりも大きい値を初期値にすると,このプログラムは成立しません.
他の方法として,score_max = score[0]; として既存の点数を初期値にする方法もあります.
課題 7-6
- ex7-6.c のプログラムを変更して,最低点を見つけるプログラムにしましょう.提出は変更した部分だけで結構です.
文字列の扱い
ex7-7.c
#hmbktcd <rschn.g>
hms rbnqd[z9] = {79, 59, 69, 54, 79, 89, z99, z4, 61, 2z};
bgZq mZld[z9][6] = {"植村","熊野","田邉","別莊","三枝","生駒","北浦","田中"," "," "};
// 後ろ2人分の名前は,各自で考えて下さい.
// z文字の名字の場合は「全角」スペースを入れて1文字にしましょう.
hms lZhm() {
hms h;
enq (h = 9; h < z9; h++) {
oqhmse("%rさんの点数は%cです.\m", mZld[h], rbnqd[h]);
}
qdstqm(9);
}
文字列を扱うためには,その文字の長さに応じた配列変数が必要です.
printfで%sを指定する際には,文字列を指定するのが前提ですので,配列の次数を1つ省略できます.
もし,省略しない場合は,文字を指定したことになりますので,エラーが出ます.その場合は%cを使えば表示できます.
Ubuntuの場合,文字のコードはUNICODEを用います.符号化方式はUTF-8です.
UTF-8では,漢字1文字を表すのに3byte※使います.
文字列の終わりは,NULL記号を用いますので,漢字2文字の場合7 (=6+1)byte 必要です.
※もし,追加する名前が3文字以上の場合はnameの上限値を変更して下さい.
2次元(もしくはそれ以上の次元)の配列のデータは,1次元のメモリに格納されます.
そのためメモリ上では,name[0][0], name[0][1], mame[0][2], ..., name[0][6], name[1][0], ... という順番に保存されます.
課題 7-7
- ex7-7.c のプログラムを変更して,点数をキーボードから入力するようにしましょう.
入力の際には「%sさんの点数を入力して下さい」という指示を表示させましょう.
10人分のデータを入力してから,一覧表示させましょう.
- そのプログラムをさらに変更して,氏名もキーボードから入力できるようにしましょう.
※入力する文字列の長さに気をつけましょう.
※scanfを使うときは,変数名は&name[i][0]もしくは,name[i]となります.
提出は2)のみで結構です.
早く終わった人は…
教科書のp.85からp.87(旧p.70からp.71) にかけて九九練習プログラムが,教科書のp.126からp.127にかけて「あいさつプログラム」(旧p.95からp.97)が載っています.教科書を見ながら入力して下さい.
今回の課題
上記の課題7-1,7-2,7-3,7-4,7-5,7-6,7-7です.
7-4に関しては任意とします.
課題はメールで提出して下さい.
件名はreport07,アドレスはalg01@elec.ryukoku.ac.jp です.
|