Lecture 3 制御文1

制御文は,コンピュータ・プログラミングの要のひとつです. 様々なセンサの値や計算値の結果などに応じて対処を変えるようなことが コンピュータには求められます.例えば,電子レンジは,温度と時間を計測して, 熱量を上げたり下げたりしますし,皆さんが持っている携帯電話も 指で触ると画面が明るくなったりします. これらは皆,コンピュータが条件を検査して, それに応じて処理を変化させている結果です. 今回はそのような条件分岐やループなどの制御文について学習します.

if文

// コード例
#include <stdio.h>
int main(void) 
{
	int x = 1;
	if(x>0) {
		printf("x is bigger than zero.\n");
	}
}

if文は,条件文(conditional statement)と呼ばれるCの文の種類の一つである.その動作は, (true) と (false) のどちらか一方に評価される条件式の結果によって決まる.if文の最も単純な形は,以下のようになる.


  if(式) 文;

「式」には任意の式を書くことができる.「文」は,式が真と評価された場合のみ実行され,式が偽と評価された場合は「文」は実行されずに次の行に処理が進んでしまう.通常,if文の式では関係演算子(下の表参照)を使って値を比較する.

例えば, 3 > 2 は真(true, 関係演算子の演算結果は1)で,2 > 3は偽(false, 演算結果は0)である.次のif文を実行すると画面に「true」と表示される.

    if(3 > 2)  printf("true");

しかし,次のif文では,演算結果が偽となるので,その次の文は実行されない.

    if(2 > 3)  printf("これは実行されない.");

また,if文の内部には,関係演算子だけではなく,あらゆる整数値を置くことができる.例えば,以下の文も成り立つ.

    int x;
    ...// x を使った計算
    if(x)  printf("xは0ではない.");

else文

// コード例
#include <stdio.h>
int main(void) 
{
	int x = 1;
	if(x>0) {
		printf("x is bigger than zero.\n");
	} else {
		printf("x is a negative or zero value.\n");
	}
}

if文にelse文を組み合わせることによって,より複雑な条件を記述することができる.

    if(式)  文1;
    else  文2;

if文の中の式を評価し,真であれば文1だけを,偽であれば文2だけを実行する.


else文に,if文を重ねる事によって,複数の式を評価することができる.

    if(式1)  文1;
    else if(式2) 文2;

コードブロック

コードブロックは,複文とも呼ばれ,一連の文を左中括弧"{"と右中括弧"}"で囲んで作る.このような複数の文は,単一の文と同様に扱うことができる.

    if(式1) {
        文1;
        文2;
    } else	// ここで改行しても問題ない
    if(式2){
        文3;
        文4;
    } 




繰り返し(ループ)のあるプログラム

コンピュータは人間と違って疲れを知りません.何度も何度も繰り返して計算することが得意です. 今度は繰り返し(ループといいます)のあるプログラムを作ってみよう.
int main(void) {
   printf("1 Hello!\n");
   printf("2 Hello!\n");
   printf("3 Hello!\n");
   printf("4 Hello!\n");
   printf("5 Hello!\n");
   printf("6 Hello!\n");
   printf("7 Hello!\n");
   printf("8 Hello!\n");
   printf("9 Hello!\n");
   printf("10 Hello!\n");
}
この(悪)例のように,ループを使わずに書き並べて同じ結果にすることも出来なくはありません. ですが,「1万回しゃべって!」だったらどうしますか? 書き並べられませんよね? こんな時にはループを使うと簡単に実現できます.
【ヒント】「データ」->「変数を作る」で,変数 i を作って使いましょう.

【ex3-2 C言語バージョン】
一行に1つずつ,1から10まで数えて表示して下さい.


スクラッチの書き方に似せたスタイル <whileループ利用>
#include <stdio.h>

int main(void) {
    int i = 1;                    // 変数iを作って値を1にする.
    while(i<=10){                 // 10回繰り返す.より正しくは条件が真である間繰り返す
        printf("%d Hello!\n", i); // iを表示します.
        i++;                      // iを1つずつ増やす.
    }
}

C言語の一般的なスタイル <forループ利用>
#include <stdio.h>

int main(void) {
    for(int i=0; i<10; i++){	    // 変数iを作ります.0始まりにすることが多いです.
        printf("%d Hello!\n", i+1); // 0始まりなので1を足して表示します.
    }
}
C++言語の一般的なスタイル <forループ利用>
#include <iostream>
using namespace std;

int main(void) {
    for(int i=0; i<10; i++){	          // 変数iを作ります.0始まりにすることが多いです.
        cout << i+1 << " Hello!" << endl; // 0始まりなので1を足して表示します.
    }
}


whileループ

whileループは次回に習いますが,C言語でよく使われるループ文の一つです.
    while(式)文;
whileループは,式が真である間,文の実行が繰り返され,式が偽になると終了します. 式の値は,文が実行される前に評価されます. つまり,最初から式が偽であれば, 文は一度も実行されないことになります.

forループ

forループを用いると,繰り返し計算することができる.

    for(初期設定部; 条件判定部; インクリメント部)文;
一番簡単で,かつ常套手段的に用いられる例を以下に示す.この例では,1から10までの値を足している.
    int sum = 0;	// 初期化
    for(int i=0; i<10; i++) {
        sum += i+1;
    }
    printf("sum = %d\n", sum);
ここで i はループカウンタと呼ばれる変数で,どのような名前をつけても構わないが,数学での慣例に則り,i, j, k などが用いられることが多い. i++ および sum += ... は,インクリメント演算子と呼ばれるものであり,実行一回につき値を一つ増やす.詳しくは次の節で説明する.

インクリメントとデクリメント

前の節に出てきた,
    i++;
の++は,インクリメント演算子といい,
    i = i+1;
と等価である. 同様に,i--; は,デクリメントで,値を一つ減らす. また,
    sum += a;
は,
    sum = sum + a;
と等価である.これも,sumから値を減らしていく場合は,
    sum -= a;
sumにaを掛ける場合は,
    sum *= a;
割る場合は,
    sum /= a;
である.

インクリメント演算子の位置による結果の違い

インクリメントと代入を一行で行う場合,演算の実行順序に気をつける必要がある.
    int i = 0;
    int j = i++;
上記の演算の場合,J の値は0である.インクリメントの演算は,iの値をjに代入した後に行われる. ところが,インクリメント演算子は,変数の前に置くこともでき,
    int i = 0;
    int j = ++i;
と書くこともできる.この場合,演算結果は異なり,jの値は1である.インクリメントは代入に先んじて実施され,iを1にしてから代入される.

関係演算子

演算子 関係
> ~より大きい
>= ~より大きいか,等しい
== 等しい
<= ~より小さいか,等しい
< ~より小さい
C/C++では,関係演算子は「演算子」であり,従って演算結果は数値となることを認識せよ. 関係演算子による演算結果は,真の場合非ゼロ(多くの場合は1),偽の場合はゼロとなる.以下のプログラムの結果を確認せよ.
printf("関係演算子の演算結果: 3>2=%d, 3<2=%d\n", 3>2, 3<2);

論理演算子

論理演算子は,AND, OR, NOTがあり,真偽の演算を行う.
論理演算子 説明
&&
AND(論理積)
||
OR(論理和)
!
NOT(否定)
論理演算の結果を次の表に示す.
a b a&&b a||b !a
0
0
0
0
1
0
1
0
1
1
1
0
0
1
0
1
1
1
1
0
ヒント:ANDはどちらか一方でも0なら,演算結果は0である.
ヒント:ORはどちらか一方でも1なら,演算結果は1である.
ヒント:NOTは単純に論理が反転する.



Quiz 3(第3回の提出課題ではありません)

以下の問それぞれに対応するプログラムを作成してみよう.
    1. 【for文】 以下のように等差数列を表示するプログラムを作ろう. ただし,初項をa=7,公差d=3とし,表示させる項数は10とします.
      【実行例】
      > Q3-1
       7 10 13 16 19 22 25 28 31 34
      >
      

      例えば,以下のようにした場合,足らないところを埋めてみてください. どうしたら,上の実行結果の例のように計算して表示出来るでしょうか?
      
      int main(void)
      {
          int a =  7;
          int d =  3;
          int n = 10;
      
      }
      
      Cのコードがわからない場合,まずはスクラッチで書いてみよう.

      解答例 Q3-1a


      解答例 Q3-1b - 関数を使った例



    2. 【for文】九九のひとつの段を表示するプログラムを作成しなさい。何の段(1~9)であるかをキー入力します。
      【実行例】
      > Q3-2
      > 何の段ですか?(1-9):5
       5 10 15 20 25 30 35 40 45
      >
      

      解答例 Q3-2



    3. チャレンジ!【for文,if文】乱数を利用しサイコロ(目の数1~6)をn回振り, 6が出た割合を表示するプログラムを作成してください. 乱数の生成には rand() を使用します.
      【実行例】
      > Q3-3
      サイコロを何回振りますか?: 1000000
      6が出た割合は 0.166697 です.
      

      例えば,以下のようにした場合,足らないところを埋めてみてください.
      #include <stdlib.h>	// rand()を使うために必要です.
      
      int main(void)
      {
          int n=0, x=0;
          printf("kaisuu:");
          scanf("%d",&n);
          printf("me no kazu:");
          scanf("%d",&x);
      
          int count = 
      
          float p = (float)count/(float)n;
          printf("%dが出た割合は%fです.\n", x, p);    
      }
      

      解答例 Q3-3



    4. チャレンジ! 【for文,if文】キー入力した数が素数かどうかを判定するプログラムを作成しなさい。
      【実行例】
      > Q3-4
      > 正の整数を入力してください:17
      17は素数です.
      >
      
      【ヒント】ある数 n が素数かどうか判定する最も簡単な方法は, 2〜n-1 までの数で割り切れるかどうかを調べることです.

      解答例 Q3-4






Assignment 3(第3回の宿題)

課題の提出は Online Judge にて行います.

  • 提出期限があります.できるだけ早めにやりましょう.
  • Online Judge は普通の課題提出方法とは異なり,良い点が取れるまで何度でも挑戦できます.良い点が取れるまで頑張ってやろう.
  • わからないことは,早めに Teams で聞こう.問題は自分で解決すること.
  • それでもどうしてもわからないときは,毎週月曜日の5時限目にZoomによるオフィスアワーを用意しています. ZoomのリンクはOh-o! meijiで確認してください.
  • Online Judge のページはこちら











QUIZのヒント

Quizも課題も,すべてC言語のコードを書くことが目的です. スクラッチは,Cの文法がわからなくても論理構造を考えられるようにするために 導入しているものです.

    1. この問題のスクラッチによるプログラムは以下のようになります(一例です.別の書き方もあります).

    2. この問題のスクラッチによるプログラムは以下のようになります(一例です.別の書き方もあります).