情報処理1 解説サイト

制御文2

授業のおさらいと課題を解くにあたっての考え方について簡単に解説したいと思います.

  • if~else文
if(条件式){
    処理1
}
else{
    処理2
}

elseは「~でなければ」という意味です.条件式が成り立つのであれば処理1が実行され,そうでなければ処理2が実行されます.つまり,elseを用いることで処理の選択を行うことができます.
ある条件が成り立つときのみ処理を行いたい場合はif文の基本形を用いて,条件成立の可否によって処理を違うものにしたい場合はif~else文を用いるようにしましょう.

if(条件式1){
    if(条件式2){
        処理1
    }
    else{
        処理2
    }
}
else{
    処理3
}

上のようにif文の中にif文を記述する入れ子の構造をとることもできます.

条件式1が成立し条件式2も成立する場合は処理1,条件式1が成立し条件式2は成立しない場合は処理2,条件式1が成立しない場合は処理3が行われます.

  • switch文
switch(条件){
    case 定数1: 
        処理1 
        break;
    case 定数2:
        処理2
    case 定数3: 
        処理3 
        処理4 
        break;
    default: 
        処理5 
        break;
}

if文は条件式成立の可否によってプログラムを2つに分岐することができました.switch文は条件の値によって,一度にたくさんの分岐をさせたい場合に用います.if~elseをたくさん記述すれば同様の処理が行えますが,switch文の方が簡潔な表現が行えます.

条件の値と一致するcase文の処理を行い,break文がない場合は,プログラムが次の文へと落ちていきます.上の場合,条件が定数1であれば処理1,条件が定数2であれば処理2,3,4,条件が定数3であれば処理3,4,条件がどの定数とも一致しない場合は処理5を行います.

  • 多重ループ
for(初期化式1;条件式1;値変化1){
    for(初期化式2;条件式2;値変化2){
        処理1
    }
}

for文による繰り返しは前回紹介しました.前回紹介した繰り返しは単純な構造でしたが,上のように繰り返しの中で繰り返しを行うことで2重の繰り返しが行えます.


以上が,授業のおさらいです.しっかりと復習をしておきましょう.
では,課題の考え方について解説したいと思います.

  • 5組

1. キーボードから整数を入力し,その数が11の倍数または17の倍数,かつ,1000以上2000未満に該当する数かどうかを表示せよ.

キーボードから整数を入力する部分はもうできると思います.ポイントは問題文を満たす条件分岐の記述です.
”かつ”と”または”をしっかりと意識して条件文を記述しましょう.論理演算子"かつ"は"&&","または"は"||"でした.今回は1つの条件式でも,if文のネストを使っても,解けると思います.ここで

if(条件式1);
    処理1

のようにすると処理1はif文とは関係のない文となり,必ず実行されてしまいます.if文の条件式の後ろにセミコロンは付けないように注意しましょう.
倍数の判定は剰余が0であるか否かです.剰余の演算は第3回の講義ページを復習しましょう.また等価性の演算子は"=="でした.代入"="と間違えないようにしましょう.
等価演算子や関係演算子は2項演算子です."a==b==c"や"5<=a<10"は正しく判定されません."a==b && b==c"や"5<=a && a<10"と記述しましょう.

if(11の倍数 または 17の倍数){
    if(1000以上 かつ 2000未満){
        処理1
    }
    else{
        処理2
    }
}
else{
    処理3
  }
if((11の倍数 または 17の倍数) かつ (1000以上 かつ 2000未満)){
    処理1
}
else{
    処理2
}

2. キーボードから西暦を入力すると,その年が閏年かどうかを表示せよ.閏年については,ここ(国立天文台)を参照

ポイントは課題1と同じです.正しく条件文を記述しましょう."400で割り切れない年"は"400で割った剰余が0ではない年"です.

3. 前の課題を参考にして,「西暦」と「何月」かを入力すると,その月は何日あるかを表示せよ.月に1-12以外の数値が入力されたらエラーを返すこと. もちろん,閏年を考慮すること.

練習問題Q3と課題2を組み合わせることで解くことができます.2月の場合にその年が閏年であるか否かの判定をします.

if(month==2){
    if(year%4==0){...
case 2:
    if(year%4==0){...

4.今日の最高気温を実数で入力すると,「夏日」「真夏日」「猛暑日」「それ以外」のいずれかを画面に表示するプログラムを書きなさい. 用語の定義については,各自で気象庁のWebページを調べること.ソースコード中にコメントとして情報元のWebサイトURLや書籍名をコメント/**/として記入すること.

if~else if~else文を用いることで簡潔に記述できると思います.

if(temperature < ??){
    printf(" ... ");
}
else if(?? <= temperature && ... ){ ...


5.じゃんけんの勝敗判定を行いたい.グー=0,チョキ=1,パー=2として,A君とB君の2人の手を入力すると,勝敗またはあいこを判定して表示せよ.入力エラー処理も行うこと.

if~else if~else文やswitch文を用いて正しく条件分岐をしましょう.条件式は2人の手の組み合わせを9通り記述する方法や,数字の差をとる方法などがあると思います.



  • 6組

1.縦と横の長さを入力し,"#"で埋め尽くされた長方形を作って下さい.

この問題のループのネスト(多重ループ)で頭が混乱してしまう人はまず次の問題を説いてみてください。
「横の長さ8、縦の長さがn(入力値)の長方形を作ってください。」
この問題は次のようになると思います。

for(int i=0; i<n; i++){
     printf("########");
     printf("\n");
}

このコードなら混乱せずに理解できると思います。このコードは次のようにも書けます。見た目は違いますが全く同じ結果になります。

for(int i=0; i<n; i++){

      printf("#"); 
      printf("#"); 
      printf("#"); 
      printf("#"); 
      printf("#"); 
      printf("#"); 
      printf("#"); 
      printf("#");        

      printf("\n");
}

とても頭の悪い書き方ですね。ではこの繰り返している部分をfor文で書き換えてみましょう。


2.縦と横の長さを入力し,"#"で埋め尽くされた逆三角形を作って下さい. ただし,縦の回数が終わったらそのままプログラムを終了させ, 横の#がなくなった場合も終了してください.

問題2は問題1と似ていますね、問題1では横に繰り返す回数が入力した定数でしたが、問題2では横の繰り返し回数が変わってきます。この場合は2つめのループで1つ目のループで使用している変数を使用することで横の繰り返し回数を変化させることができます。

for(int i=0; ...){
       for(int j=0; /*ここでiをつかう*/ ; ... )
       ...

3.for文を2回使用して以下に示すような九九の計算結果を表示するプログラムを作りなさい. このとき,桁をきちんと合わせて表示すること.

for文を2回使う参考として、以下のソースを例に作成して見てください.

for(int row=1; ...){
		for(int col=1; ...
			int val = ...;
			
			printf(" %2d", val);
			...
		}
}

九九を表示する上で、まずかける数とかけられる数(row,col)を作ります.for文の中にfor文を入れることで 『row= 1 の時 col のfor文が始まり, col の for文が終わると,rowの値が1つ増え,またcol のfor文が始まる … 』となります.
また、今回の課題では桁をきちんと合わせて表示をしなければなりません.そこで用いられるのが

	printf(" %2d", val);

という形です.今までは %d という形を使われていたと思うのですが,% と dの間に数字を入れることで,その数分のスペースを確保しての表示をすることが出来ます.
今回では2桁の数に揃えるべきなので %2d を用いることになります.



4.switch文を使って,1, 2, 3の入力に応じて,入力した数字が表示されるプログラムを書いて下さい. それ以外の数字の場合は,繰り返し1-3の数字の入力を求め,0が入力されたら終了するようにしてください.

この問題では,switch文の条件に当たる変数こそが入力値になります.また,入力値が0となるまでプログラムを実行し続けなければならないため,以下のようにコーディングする必要があります.

        while(. . .){
                switch(. . .){
                       case 1:
                       . . . 
                }
        }        

ポイントは,どのようにwhile()ループを抜けるかという点ですね.


5.while文を用い (0<=x<=2π) の範囲で,f(x)=sin(x) の極大値fmax(a)とその位置 a を探索し求めよ. なお探索時のxの刻み幅 dx=0.0001 とする.

この問題では高校数学で予想はつくと思うのですが、極大値とはどのような値なのか今一度考えてみてください.
ここで登場する

#include<math.h> 

とは,数値演算の関数が詰まったライブラリになってます.ここではsin(x)の関数を用いるために宣言をします.今後様々な関数を使うことがあるので覚えておきましょう.
while文を用いる上でどのタイミングでプログラムを終了させるか考えないと終わらないことにも注意してください.終わらせるやり方は授業ページを見直しましょう.