2000.07.14 KPC 情報技術科 関谷
問題文とプログラムの例を見て、次の下線部分のように訂正するのが良いと思われる。
『東西方向が青信号になったときの東西の車の待ち行列をew(台)とし、また東西方向が青信号のときの交差点での南北の車の待ち行列をqns(台)とします。』
小生のプログラム例(下に引用)は、反復を使って、青信号から黄色に変わるまでの時間をシミュレートする。計算の部分は、テキストの処理を使っている。なお、南北方向の待ち行列は、時間がたてば増加するはずだが、ここでは、簡略化して一定としている。
/* rei3_2a.c, 2000.7.14, KPC sekiya, 中津山-Cプログラミング入門、p.31-32 */ /* 青信号の継続 */ /* 考察 1.whileを使い、青の継続時間をすべて表示する。 */ /* プログラム仕様 ・入力:なし ・処理:whileを使い、青の継続時間をすべて表示する。 ew:東西方向が青信号になったときの東西の待ち行列、15 qns:東西方向が青信号の間の南北の待ち行列、8 sgew:東西方向信号、0:青、1:黄色、2:赤 ・出力:t,ew,qns */ #includemain() { int ew=15, qns=8, sgew=0, t=0; printf("rei3_2a.c, 2000.7.14, KPC sekiya\n"); printf(" 青信号の継続を計算\n"); printf("青信号の継続t 東西の待ち行列ew 南北の待ち行列\n"); while(sgew == 0) { if(sgew == 0 && ew > qns) { ++t; --ew; } else if(sgew == 0){ sgew = 1; t = 0; } printf(" %2d 秒 %2d 台 %2d 台\n", t, ew, qns); } } /* 実行結果 H:\c00>rei3_2 rei3_2a.c, 2000.7.14, KPC sekiya 青信号の継続を計算 青信号の継続t 東西の待ち行列ew 南北の待ち行列 1 秒 14 台 8 台 2 秒 13 台 8 台 3 秒 12 台 8 台 4 秒 11 台 8 台 5 秒 10 台 8 台 6 秒 9 台 8 台 7 秒 8 台 8 台 0 秒 8 台 8 台 */
テキストの例では、1つのケースのみを変数の初期化により表示している。「プログラムをデバッグする」(プログラムが正しく動作することを示す)ためには、すべてのケースでテストしてそれらが正しいことを示したい。これには、すべての条件の組み合わせを作って確かめると良い。
小生の以下のプログラムは、この条件の組み合わせに、反復を2重にしている。
/* rei3_3a.c, 2000.7.14, KPC sekiya, 中津山-Cプログラミング入門、p.32-33 */ /* エレベータの動く方向 */ /* 考察 1.配列を使い、t1,t2,epの組み合わせをすべて表示する。 */ /* プログラム仕様 ・入力:なし ・処理:t1,t2,epの組み合わせをすべて計算して動く方向を表示する。(2重のfor) ・出力:t1,t2,ep,up */ #includemain() { int i, j, k, t1=10, t2[]={9,10,11}, ep[]={1,2}, up; char str_up[][13] ={"そのまま開く", "上昇する", "下降する"}; printf("rei3_3a.c, 2000.7.14, KPC sekiya\n"); printf(" エレベータの動く方向をt1,t2,epの組み合わせですべて計算\n"); printf("スイッチt1 スイッチt2 エレベータの位置ep 動く方向up\n"); for(j=0; j<3; j++) for(k=0; k<2; k++) { if(t1 == t2[j]) up = 0; else if(t1 > t2[j]) up = ep[k] == 2 ? 0: 1; else up = ep[k] == 1 ? 0: 2; printf(" %2d %2d %d %d : %s\n", t1, t2[j], ep[k], up, str_up[up]); } } /* 実行結果 H:\c00>rei3_3 rei3_3a.c, 2000.7.14, KPC sekiya エレベータの動く方向をt1,t2,epの組み合わせですべて計算 スイッチt1 スイッチt2 エレベータの位置ep 動く方向up 10 9 1 1 : 上昇する 10 9 2 0 : そのまま開く 10 10 1 0 : そのまま開く 10 10 2 0 : そのまま開く 10 11 1 0 : そのまま開く 10 11 2 2 : 下降する */
do-whileループ(反復の後判定)を使うと、プログラムが簡単になるケースがある。
文字をコピーした後で判定するため、条件式の参照では while(s[i++] != '\0'); としている。
場合分けがたくさんあるときに、switch文が有効である。
演算子の入力をするとき、演算子の後にEnter('\n')も読み込むため、テキストの通りにするとwrong operatorのメッセージが出て、2行に分かれての重複表示になってしまう。これを回避するには、switch(c){の前に、if(c == '\n')ならcontinue;とする。
default:では、wrong operatorのメッセージ出力の後、break;となっているため、1つ前の演算子の結果を続けて書いてしまう。これをさけるには、break;の替わりに、continue;(whileの終端に飛ぶ)のが良い。
ここでも、演算子の入力でトラブルになる。演算子の入力後に、'\n'を読み飛ばすのが良い。 (switch(){文の前に、getchar();を追加する。)
問題文に説明しているように、文字列を倍精度浮動小数点に直す関数atof(s)を用いて、ニュートン法のプログラムのvに代入すれば良い。
関数atof(s)は戻り値がdoubleであるから、intを返すatoi()を違ってプロトタイプ宣言が必要である。#include
上の問題に限らないが、プログラムの作成では、新規に作成するよりも、似た構造の既存のプログラムを利用して、それの編集(追加・削除など)をするの良い。編集作業には、テキストエディタが役に立つ。
プログラムを作りテストする場合、2つの窓を開いて、ソースの編集とコンパイル・実行を交互に窓を切り替える(あるいは並べておいてクリックする)方が、1つの窓でエディタを起動/終了してコンパイル・実行するよりも便利である。データ入力・チェックプリントをソースと比較することもできる。
(注意事項)2つの窓でプログラムをテストするときには、ソースの変更後の保存先(上書き)が、コンパイルしているカレントディレクトリになっていること。違っていれば、如何に正しく修正しても、結果が正しくならないことになる。
わかり易いプログラムを作ることを目的に、C言語プログラムの様式についてまとめているので、それを参考にして、今後作るプログラムを作ってほしい。
JIS流れ図の記号では、反復には家型の記号が用意されているが、C言語での表記と一致しにくい場合がある。初期設定、分岐、終端での処理と3つに分けて書けば分かりやすい。
レポートは、実習した1本のプログラムを選び、レポート用のテキストファイルを作り、それにコピーして作成のこと。
・フォルダ:w:\アプリケーション演習¥C言語do,switch7.14 ・ファイル名:nn氏名プログラム名.c