第4回 条件分岐 と 繰り返し

宿題をまずは確認しよう。

A君とBさんがじゃんけんをする.グー=1,チョキ=2,パー=3として,A君とBさんの手をそれぞれ入力すると,A君とBさんのどちらが勝ったのかを判定するプログラムを今回は作ります。

  1. A君とBさんの出す手の、考えられる組み合わせとそのときの勝敗を表にする。
  2. プログラムの流れを、フローチャートに書く。

プログラム全体の流れを考える

まずはフローチャートを作成し,プログラム全体がどのような流れになるかを,必ず紙の上で行おう。

登場するデータを考える

じゃんけんを行うのに必要となる変数,何が必要か考えよう。

データ入力

じゃんけんの手を,キーボードから入力しよう。
「グー」などの入力は面倒なので,グー=1,チョキ=2,パー=3として,数字を入力するようにする。

データ処理

じゃんけんプログラムでは,入力された手を比較して,勝ち負けを判定します。
二人の出す手の組み合わせは全部で9とおり。これを正直に書くと,以下のようになります。


#include <stdio.h>

 
void main()
{
    /* 変数の定義 */
    int a, b;    

    /* 入 力 */
	....
	
    /* 処 理 */
	if(a == 1 && b == 1){
		printf("あいこです\n");
	}else if(a == 1 && b == 2){
		printf("A君の勝ち\n");
	}else if(a == 1 && b == 3){
		printf("Bさんの勝ち\n");
	}else if(a == 2 && b == 2){
		printf("あいこです\n");
	}else if(a == 2 && b == 3){
		printf("A君の勝ち\n");
	}else if(a == 2 && b == 1){
		printf("Bさんの勝ち\n");
	}else if(a == 3 && b == 3){
		printf("あいこです\n");
	}else if(a == 3 && b == 1){
		printf("A君の勝ち\n");
	}else if(a == 3 && b == 2){
		printf("Bさんの勝ち\n");
	}

	/* 出 力 */
	....
}


今日の課題1

上の条件分岐を参考に,じゃんけんプログラムを完成させよう。

今日の課題2

上の条件分岐は,間違いではありませんが,ちょっと正直すぎます。場合分けを「勝ち」,「負け」,「あいこ」の三つに整理してみよう。


じゃんけんの改良

ここまでできたら,何度かじゃんけんプログラムを実行してみて,改良したい点,おかしな動きをする点を見つけよう。

改良するための技 繰り返し

一つの改良点は,あいこでプログラムが終わらないようにしたい。
あいこの場合を処理するにはどうしたら良いでしょうか?

繰り返し処理(while文の書き方)

コンピュータは同じ処理を何度も繰り返し実行するのが得意です。
C言語では処理を繰り返す仕組みとして while文,for文 が用意されています。

まず while文 を説明します.

while文のフローチャートは,

while ( 条件式 ) {   文1; }

と書き,条件式が「真」である間,文1の処理を実行を続けます。

「じゃんけん」の問題を繰り返し処理を用いると,おおよそ次のようになります。


#include <stdio.h>

void main()
{
 	int a,b,win;

	win=0; /* あいこ:0、aの勝ち:1、bの勝ち:2 */
 
	while(win==0){
		printf("a君とb君がじゃんけんします.\nグー : 1 チョキ : 2 パー : 3\n");
 	
		printf("a君は何を出しますか?\n"); scanf("%d",&a);
 		printf("b君は何を出しますか?\n"); scanf("%d",&b);
 
		if(。。。。){....}
	}

	if(win==1){
		printf("Aが勝ちました\n");
	}else{
		printf("Bが勝ちました\n");
	}
}



今日の課題3

あいこだと繰り返すじゃんけんプログラムを完成させよう。


カウンタを用いた繰り返し処理の制御(while文)

たとえば,「画面に 1 を 10 行表示するプログラム」を組む場合。



#include <stdio.h>
 
void main()
{
    printf("1¥n");
    printf("1¥n");
    printf("1¥n");
    printf("1¥n");
    printf("1¥n");
    printf("1¥n");
    printf("1¥n");
    printf("1¥n");
    printf("1¥n");
    printf("1¥n");
}
 

とすれば,とりあえず結果は得られるものの, 10が10000になったらプログラムを入力するのが大変なことになってしまう.

このプログラムでは 1 を表示するという行を何度も繰り返している. そこでwhile文を用いて1を表示させ続けるには,


#include <stdio.h>
 
void main()
{
    while (1) {         /* 無限ループ(注)プログラムが止まらなくなるので注意 */
 
        printf ( "1¥n" );     
 
    }
}
 

しかし、このプログラムのままでは永遠にprintf()を実行してしまい問題がある.
  (注)プログラムの停止方法は無限ループの項を参照すること

では,作業を決まった回数だけ繰り返すにはどうしたらよいだろう?

ここで,いま何回目の計算を行っているのかを覚えておくためにカウンタ変数という考え方を導入しよう.
つまり,

1-1 カウンタ変数を宣言する

1-2 カウンタの値を 0 にクリアする

2 カウンタの値が 決まった値以下では以下の処理を繰り返す

 2-1 実行文を実行する
 2-2 カウンタの値に 1 加える


表の処理をフローチャートにまとめると

5_2.png

while

式1;
while ( 式2 ) {
文1;
式3;
}

式1 初期値設定 繰り返し実行の直前に1度だけ実行される.カウンタの初期値設定などに使う.
式2 反復条件 繰り返しを継続する条件を書く.この条件式がの間は繰り返す
式3 付加実行式 繰り返しを1度行うごとに実行したいことを書く.
文1 実行文 繰り返し実行する文

となる.カウンタを用いることにより実行回数の制御が出来きることがわかる.

今度は,実際にwhile文 を用いるたプログラムを見てみよう,

上記の10回だけ画面に1を表示するプログラムにwhile文を用いる.


#include <stdio.h>
 
void main()
{
    int i;	/*カウンタ変数の宣言*/
 
    i = 0;    /* (式1)カウンタの値を0に.重要!これを行わないと i に何が入っているかわからない! */
 
    while (i < 10 ) {         /* (式2)カウンタの値が10未満( 0 ,1,2, ... , 9 ) の場合,以下を繰り返す */
 
        printf ( "1¥n" );      /*(文1) 繰り返したい処理.(ここでは画面に1を表示) */
 
        i++;                /* (式3)カウンタの値に1加える */
 
    }
}

となる.

ここで,i++ は,i の値を 1 増やすことを表し,i = i + 1 と等価である.繰り返しでよく使う演算子.

変数 i を while 文でカウンタとして利用するときは,繰り返し文の前にゼロクリア(初期化)を忘れないように!!!

i=0;から始めるとすると,
while ( i < 10 ) では,i は 0 から 9 まで変化するので10回の反復になるが,
while ( i <= 10 ) では,i は 0 から 10 まで変化するので 11 回の反復になるので注意!



応用

練習で作成したプログラムを利用して,画面に 1 から n までの数字を表示してみよう.


#include <stdio.h>
 
void main()
{
    printf("1¥n");
    printf("2¥n");
    ・・・;
    printf("n¥n");
}
 

また元に戻ってはしょうがないので, while文 を使うことを考える.

このプログラムをよく見ると,printf 文 を何回も繰り返していますが,中身が毎回変化している.
そこで,前のプログラムで用いたカウンタ(繰り返しの回数を数えている変数 i )をうまく利用すると,


#include <stdio.h>
 
void main()
{
    int i, n;
 
    printf ("n= " ); scanf ( "%d", &n );
 
    i = 0;         /* カウンタの値を0に */
 
    while ( i < n ) {         /* カウンタの値が n 以下の場合,以下を繰り返す */
 
        printf ( "%d¥n", i );     /* 画面にカウンタの値を表示する */
 
        i++;                   /* カウンタの値に1加える */
    }
}
 


無限ループ

繰り返しを無限に繰り返し,プログラムが終了しなくなってしまうことを,無限ループと呼ぶ.

たとえば,while文 で判定する式が偽に成り得ない(常に真)となると,その繰り返しは終了しなくなる.

しかしながら計算手法によっては,意図的にこのような繰り返しを行う場合もある.

例:



    while(1) {    /*  これは無限ループ  */
        ・・・・;
    }

プログラムが意図せずこのような状態になったら,キーボードから [ctrl] + [c] (コントロールキーを押しながらcを押す)と入力して,プログラムを強制終了させることができる.


演習課題 (Oh-Meiji で提出)

(4)九九の九の段を表示するプログラムを作成しなさい。

   ヒント:カウンタを上手に使うとプログラムがシンプルに作成できる

(5)1から,入力した値 n までの和を求めるプログラムを,while文を用いて作成せよ。

(6)じゃんけんプログラムを,自分のアイディアに基づき改良しよう。

参考 乱数

コンピュータの出す手は,ランダムにしたい! -> 乱数


#include <stdio.h>

#include <stdlib.h>

void main()
{
    int b;

	randomize();    /* 乱数発生ルーチンの初期化 */
	b = rand() % 3;  /* 0 ~ 2 の間の数字を発生 */
}

授業終了時までのプログラムと完成した提出用プログラムをoh-meijiシステムを使って提出すること
授業終了時に送るのは出席の確認用である.完成した課題は提出用の回に送ること
(提出用の回に提出しないと,採点を行わない)


演習:解答例