2000年7月22日更新(atof(s)を呼ぶとき、#include を最初に追加)
  関谷トップページへ アプリケーション演習トップページへ 作者へのメッセージ

アプリケーション演習No.12 C言語プログラミング3.5do-while, 3.6switch文

  2000.07.14 KPC 情報技術科 関谷

1.3章の例題2,3についての訂正と補足

例題2 交差点の青信号の切り替え

 問題文とプログラムの例を見て、次の下線部分のように訂正するのが良いと思われる。
 『東西方向が青信号になったときの東西の車の待ち行列を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
*/

#include 

main()
{
	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 台
*/

例題3 エレベータの動く方向

 テキストの例では、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
*/

#include 

main()
{
	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 : 下降する

*/

2.今日の実習 3-5 do-whileループ、3-6 switch文、演習問題

3-5 do-whileループ(反復の後判定)

 do-whileループ(反復の後判定)を使うと、プログラムが簡単になるケースがある。

プログラム3−10 ニュートン法による平方根の計算

例題6 文字列の入力・複写・カウントと表示

 文字をコピーした後で判定するため、条件式の参照では while(s[i++] != '\0'); としている。

3-6 switch文(多重分岐)

 場合分けがたくさんあるときに、switch文が有効である。

プログラム3−11 電卓の四則演算のシミュレーション

 演算子の入力をするとき、演算子の後にEnter('\n')も読み込むため、テキストの通りにするとwrong operatorのメッセージが出て、2行に分かれての重複表示になってしまう。これを回避するには、switch(c){の前に、if(c == '\n')ならcontinue;とする。
 default:では、wrong operatorのメッセージ出力の後、break;となっているため、1つ前の演算子の結果を続けて書いてしまう。これをさけるには、break;の替わりに、continue;(whileの終端に飛ぶ)のが良い。

例題7 連続しての電卓のシミュレーション

 ここでも、演算子の入力でトラブルになる。演算子の入力後に、'\n'を読み飛ばすのが良い。 (switch(){文の前に、getchar();を追加する。)

3章の演習問題 5)任意の数を入力してその平方根を計算する

 問題文に説明しているように、文字列を倍精度浮動小数点に直す関数atof(s)を用いて、ニュートン法のプログラムのvに代入すれば良い。
 関数atof(s)は戻り値がdoubleであるから、intを返すatoi()を違ってプロトタイプ宣言が必要である。#include を最初に追加しておくこと。(詳細は、第4章関数を参照。)

プログラムの再利用

 上の問題に限らないが、プログラムの作成では、新規に作成するよりも、似た構造の既存のプログラムを利用して、それの編集(追加・削除など)をするの良い。編集作業には、テキストエディタが役に立つ。

2つの窓の利用

 プログラムを作りテストする場合、2つの窓を開いて、ソースの編集とコンパイル・実行を交互に窓を切り替える(あるいは並べておいてクリックする)方が、1つの窓でエディタを起動/終了してコンパイル・実行するよりも便利である。データ入力・チェックプリントをソースと比較することもできる。
(注意事項)2つの窓でプログラムをテストするときには、ソースの変更後の保存先(上書き)が、コンパイルしているカレントディレクトリになっていること。違っていれば、如何に正しく修正しても、結果が正しくならないことになる。

プログラムの様式について(再録)

 わかり易いプログラムを作ることを目的に、C言語プログラムの様式についてまとめているので、それを参考にして、今後作るプログラムを作ってほしい。
 JIS流れ図の記号では、反復には家型の記号が用意されているが、C言語での表記と一致しにくい場合がある。初期設定、分岐、終端での処理と3つに分けて書けば分かりやすい。

3.レポート

3.1 レポート用ファイルの作成

 レポートは、実習した1本のプログラムを選び、レポート用のテキストファイルを作り、それにコピーして作成のこと。

3.2 提出フォルダとファイル名

・フォルダ:w:\アプリケーション演習¥C言語do,switch7.14
・ファイル名:nn氏名プログラム名.c