計算数学演習第3回

条件分岐(if文)

前回のまとめ

  • 変数は必ず宣言してから用いる。(int n, double x、など)
  • 変数の代入には = を用いる。( = の右側の式の値が、左側の変数に代入される)
  • 変数の表示の仕方は整数型と実数(浮動小数点)型で違う。 printf(“%d”,n)、printf(“%lf”,x)
  • 変数の入力の仕方も整数型と実数型で違う。 scanf(“%d”,&n), scanf(“%lf”,&a)

今日の目標

  • 前回までで学んだprintf関数とscanf関数の使い方をしっかり身に付ける
  • 条件分岐を理解する
  • C言語における条件分岐の書式を覚える
  • 条件式の書式を理解する

条件分岐(if 文, if-else 文)

ブロック文

今日でてくる if 文や for, while 文ではブロック文と呼ばれるものが使われます。
ブロック文とは、文を一まとめにしたもので、{  } で囲まれています。

if 文, if-else 文

プログラムを作成していると、条件によって処理を分岐させたい場合がよく出てきます。
(下のプログラムを、ファイル名をif-1.c としてエディターで打ち込んでください。)

if-1.c

#include <stdio.h>
 
int main() {
    /* 実数型の変数 a, b, c を用意する */
    double  a, b, c;
    
    /* 実数型変数 a に入力 */
    printf("実数 a を入力してください:");
    scanf("%lf", &a);
    
    /* 実数型変数 b に入力 */
    printf("実数 b を入力してください:");
    scanf("%lf", &b);
    
    /* 実数型変数 c に a/b の結果を代入 */
    c = a/b;
    
    /* 変数 c の内容を画面に表示 */
    printf("a/b=%lf\n", c);
    
    return 0;
}

このプログラムを実行し、実数 a,b をそれぞれ入力すると、a/b の結果を画面に出力します。
ところで、 b として 0 を入力するとどうなるでしょうか?やってみると分かりますが、なにかエラーが出ます。
このように、実数型に限らず 0 で割ろうとすると実行時にエラーになる(コンパイルは成功する)ので、それを回避することを考えねばなりません。
そこで、条件文が登場します。
まずは、サンプルプログラムでみてみましょう。
先の if-1.c を次のように変更してください。
– – – – – – – – – – – – – – – –

if-1a.c

#include <stdio.h>
 
int main() {
    /* 実数型の変数 a, b, c を用意する */
    double  a, b, c;
    
    /* 実数型変数 a に入力 */
    printf("実数 a を入力してください:");
    scanf("%lf", &a);
    
    /* 実数型変数 b に入力 */
    printf("実数 b を入力してください:");
    scanf("%lf", &b);
    
    if (b == 0.0) {
        printf("0 での割り算はできません。\n");
    }
    else {
        /* 実数型変数 c に a/b の結果を代入 */
        c = a/b;
        
        /* 変数 c の内容を画面に表示 */
        printf("a/b=%lf\n", c);
    }
    
    return 0;
}

if (b == 0.0) からが条件文です。
このプログラムでは、入力された b の値が 0 に等しければ16行目が実行され、それ以外の場合は19〜23行目が実行されます。

典型的な if-else 文

if-else 文には重要なものとして次のような3つのパターンがあります。
パターン1

文0
if (条件) {
    条件が真であれば実行するブロック文・・・・ブロック文1
}
else {
    条件が偽であれば実行するブロック文・・・・ブロック文2
}
文3

パターン2

文0
if (条件) {
    条件が真であれば実行するブロック文・・・・ブロック文1
}
文2

パターン1とパターン2の違いは else 文が有るか無いかの違いです。
より複雑なものとして、次のパターン3 (3N) があります。
パターン3

文0
if (条件1) {
    条件が真であれば実行するブロック文・・・・ブロック文1
}
else if (条件2) {
    条件1が偽かつ条件2が真であれば実行するブロック文・・・・ブロック文2
}
else {
    条件1,2 どちらも偽であれば実行するブロック文・・・・ブロック文3
}
文4

パターン3N

文0
if (条件1) {
    条件が真であれば実行するブロック文・・・・ブロック文1
}
else if (条件2) {
    条件1が偽かつ条件2が真であれば実行するブロック文・・・・ブロック文2
}
・
・
・
else if (条件N) {
    条件1~条件N-1が全て偽かつ条件Nが真であれば実行するブロック文・・・・ブロック文N
}
else {
    条件1~条件Nが全て偽であれば実行するブロック文・・・・ブロック文N+1
}
文N+2

フローチャートによる説明

上記パターン1とパターン2をフローチャートで示すと次のようになります。

条件式

if 文の条件の部分には条件式が入ります。条件式は関係演算子という演算子を使って記述します。
関係演算子は2つの値の大小関係や等値関係を判定するものです。
関係演算子には次のものがあります。

演算子 説明 記述例 記述の意味
> 大きい if (a > 100) a が 100より大なら
>= 大きいか等しい if (a >= 100) a が 100以上なら
< 小さい if (a < 100) a が 100より小なら
<= 小さいか等しい if (a <= 100) a が 100以下なら
== 等しい if (a == 100) a が 100なら
!= 等しくない if (a != 100) a が 100でないなら

等しいをあらわす条件式は == とイコール2つであることに注意してください。
= とイコール1つの場合は変数への代入をあらわしていました(先週の内容)。
if 文の条件を書く部分に誤って代入式を書いたとしても、文法的には間違っていないので、コンパイルが成功してしまいます(期待した動作はしませんが)。
気をつけてください。

課題1

2つの実数 s, t を入力すると、その差の絶対値を表示するプログラムを作成せよ (if 文を使うこと)。

課題2

整数 m が入力されると、それが奇数か偶数かを判定するプログラムを作成せよ。
(注:剰余を求める演算子 % を利用. これは整数型変数m, n に対し、m%n は m を n で割ったときの余りを与える。この演算子は整数型変数にのみ利用可能。)

課題3

2つの実数 s, t を入力すると, s > t, s = t, s < t か判定して表示するプログラムを作成せよ。(If-else文のパターン3を参考)

課題4

3つの実数, a, b, c を入力すると, x に関する2次方程式, ax2 + bx + c = 0 が実数解を持つか判定し, 表示するプログラムを作成せよ。

発展編:論理演算子をつかった込み入った条件式

ときには、
「a>10」 かつ 「a<100」 なら
「a==100」 または 「a==200」 なら

といった、場合を扱いたいときがあります。
このようなかつまたはに相当する論理演算子を使うことで、より複雑な条件をあらわすことができます。
例えば、うるう年は
4で割り切れる かつ 100で割り切れない年」
400で割り切れる年
のどちらかに当てはまる年のことです。
例えば、入力された年(西暦)を上の条件に照らし合わせ、うるう年かどうかを判定するプログラムは次のようになります。
if 文の中身に注意しつつ, ファイル名を if-2.c として打ち込んで, 実行してみてください.
途中でてくる % は剰余を与えるものでした(上述)。

if-2.c

#include <stdio.h>
 
int main() {
    int n;
    
    printf("年=");
    scanf("%d", &n);
    
    if ((n%4 == 0) && (n%100 != 0)) {
        printf("うるう年です\n");
    }
    if (n%400 == 0) {
        printf("うるう年です\n");
    }
    
    return 0;
}

途中でてくる && が関係演算子で、「かつ」をあらわします。
関係演算子には && のほかに次のようなものがあります。

演算子 説明 記述例 記述の意味
&& 論理積(かつ/and) if (a == 3 && b == 4) a が 3 かつ b が 4 なら
|| 論理和(または/or) if (a == 3 || b == 4) a が 3 または b が 4 なら
! 否定(でない/not) if (!(a == 3 && b == 4)) a が 3 かつ b が 4 、でないなら

 関係演算子 && は & が2つであることに注意してください(|| も同様)。
& 1つでも他の意味がありますので、コンパイルエラーにはなりません。
しかし、期待した動作とはならないので注意が必要です

先の日本語でのうるう年の定義は
「4で割り切れる かつ 100で割り切れない年」 または 「400で割り切れる年」
と書き直すことができます。
つまり、先の2つの if 文を一つにまとめて次のように書くこともできます。

if-2a.c

#include <stdio.h>
 
int main() {
    int n;
    
    printf("年=");
    scanf("%d", &n);
    
    if (((n%4 == 0) && (n%100 != 0)) || (n%400 == 0)) {
        printf("うるう年です\n");
    }
    
    return 0;
}

課題5

入力された整数が、3 の倍数か 7 の倍数であれば、その数値を表示するプログラムを作成せよ。( || を使う。)

課題6

“3 の倍数か 7 の倍数”である三桁の自然数の入力を促し、入力された数値が 条件を満たしているかどうか画面に出力するプログラムを作成せよ。(if文は1回しか使えないものとする))

発展課題

2つの実数x,yを入力すると、点(x,y)が直線y=4x-3より上側の領域・直線上・下側の領域のどこにあるかどうかを判定し、さらに、円x2+y2=4の内部・線上・外部のどこにあるかを判定し、結果を表示するプログラムを作成せよ。

今日新しく学んだ事

  • 条件分岐

Department of Mathematical and Life Sciences, Graduate School of Integrated Sciences for Life, Hiroshima University