条件分岐

 

 これまでは、文字列、数値の表示、数値の入力について行ってきました。
今度は、数値または条件式によって異なる処理を行うということをやって行きます。

条件式とは、条件を表す式です。例としては比較等です。
ある条件式を満たすときのみに行いたい処理がある場合はif文を使います。
if文は

if(条件式){
    処理
}

と記述します。
これは、条件式を満たす((0)でない)ときに、{}で囲まれた部分に書かれた処理を行うというものです。
{}のブロックは関数のものと同様と考えてください。
このブロックは直前に書かれた文(ここではif)に関する処理の初めと
終わりを示します。
C言語では、偽(正しくない)ときは0、真(正しい)ときは0以外の値となります。
   ※   真の値は無限に存在するため、自分で真にしたい(わざと真にする)場合は一般に1を用います。
   ※   条件式を省略した場合は0以外の場合とみなされ、真と評価されます。
         つまりif文は00以外の値かのみで判断をしています。
条件式に使われる演算子と真、偽の条件を以下に示します。

 

(0以外)

(0)

==

等しい

等しくない

!=

等しくない

等しい

右の値の方が大きい

左の値の方が大きい

左の値の方が大きい

右の値の方が大きい

<=

右の値の方が右の値の値と等しいまたは大きい

左の値の方が左の値の値と等しいまたは大きい

>=

左の値の方が左の値の値と等しいまたは大きい

右の値の方が右の値の値と等しいまたは大きい

&&

左右どちらも真

左右どれか1つでも偽

||

左右どちらか1つでも真

左右どちらも偽

!

条件式が偽

条件式が真

数学では等しいときは=を、等しいまたは大きい等のときは≦等を使用していましたが、
=は値の代入に使用されているため、==と記述しなければなりません。
≦はこのような記号は認識されないので、<=と記述します。
=は右側に付くと言うことは覚えて置いてください。
間違えて左側に付けてしまい、エラーが出てしまうことが私の場合ですがよくありました。

プログラム例

#include <stdio.h>
int main(void){
    int a,b;
        scanf("%d",&a);
        scanf("%d",&b);
        if(a){
                printf("a0ではない\n");
        }

        if(a==b){
                printf("等しい\n");
        }
        if(a!=b){
                printf("等しくない\n");
        }
        if(a<b){
                printf("ab未満\n");
        }
        if(a>b){
                printf("abより大きい\n");
        }
        if(a<=100){
                printf("ab以下\n");
        }
       
if(a>=101){
                printf("ab以上\n");
        }
        if(a>b&&a>0){
                printf(
"abより大きく正の値\n");
        }
        if(a<b||a<0){
                printf("ab未満か負の値\n");
        }
        if(!(a>b&&a<0)){
                printf("ab未満か正の値\n");
        }
        return 0;
}

このプログラムでは条件式に使われる演算子すべてを用いたif文を書いています。
少々プログラムが長いですが、上から順に見て行きましょう。
まず、abの値を入力し、
最初のif文では、a0ではないつまり真のときにa0ではないを表示します。
次ぎのif文では、abが等しいとき、等しいと表示します。
次ぎのif文では、abが等しくないとき、等しくないと表示します。
次ぎのif文では、ab未満であるとき、ab未満と表示します。
次ぎのif文では、abより大きいとき、abより大きいと表示します。次ぎのif文では、a100以下であるとき、a100以下と表示します
次ぎのif文では、a101以上であるとき、a101以上と表示します。
次ぎのif文では、abより大きくかつa0より大きいとき、abより大きく正の値と表示ます。
次ぎのif文では、ab未満またはa0未満であるとき、ab未満か負の値と表示します。
最後のif文では、abより大きくかつa0より大きいという条件を満たしていないとき、ab未満か負の値と表示します。
かなり長いプログラムですが、条件式に対する処理が1つの場合、ブロックは省略できます。
以下に省略した場合のプログラム(if文のところのみ)を書きます。

if(a)           printf("aはではない\n");
if(a==b)        printf("等しい\n");
if(a!=b)        printf("等しくない\n");
if(a<b)         printf("ab未満\n");
if(a>b)         printf("abより上\n");
if(a<=100)      printf("ab以下\n");
if
(a>=101)      printf("ab以上\n");
if(a>b&&a>0)    printf("abより上で正の値\n");
if(a<b||a<0)    printf("ab未満か負の値\n");
if(!(a>b&&a>0)) printf("ab未満か正の値\n");

プログラムを見やすくするためにprintf関数の位置を揃えてあります。なるべく揃えるようにしたほうがよいです。
また、ブロックを付ける、付けないはプログラムがいかに見えやすくなるかという基準で判断します。
  ※    最初のほうで書きましたが、学校や会社のルールで決められている場合はそれに従ってください。
   ※    ブロックを書かないとif文で実行する処理は1行分( ; 1つの処理分)のみとなります ので、
      複数行分使用する場合はブロックを必ず用いてください。

#include <stdio.h>
int main(void){
        if(0)
                printf("nは真\n");
                printf("nは以外の値\n");
        if(1){
                printf("nは真\n");
                printf("nは以外の値\n");
        }
        return 0;
}

この場合、最初のif文では最初のprintf関数のみ実行されず、
次のif文では2つのprintf関数のどちらとも実行されています。

ところで上のプログラムでif(a>b)if(a>b&&a>0)if(a>b)という条件が重なっていて
同じ物を複数書いているのはあまりよくありません。この場合は以下のように書き換えたほうがいいです。

if(a>b){
        printf("abより上\n");
        if(a>0) printf("abより上で正の値");
}

if文の中にif文を書くことにより解決できます。ただし、abより上を表示させないのであれば
&&を使用して書いた方が、if文が1つだけで済み、簡潔にかけます。
a<ba<b||a<0の場合はどのようにしてもa<b2回書かなければならないのですが、
プログラムの見やすさという点では上と同様にif文の中にif文を書くというようにするのが良いです。

ある条件ではある処理を行わせ、そうでない場合は別の処理を行わせたい場合(場合分け)にはif文とelse文を使います。

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

これは条件式に当てはまる場合に処理1を行い、そうでない場合は処理2を行うというものです。
さらに場合分けを行うにはelse-if文を用います。

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

これは条件式1に当てはまる場合は処理1を、条件式1に当てはまらず条件式2に当てはまる場合は処理2を行います。
また、else-if文のあとにelse文を書くこともでき、いろいろと組み合わせが可能です。 

プログラム例

#include <stdio.h>
int main(void){
    int a,b;
        scanf("%d",&a);
        scanf("%d",&b);
        if(a==b){
                printf("等しい\n");
        }else{
                printf("等しくない\n");
        }

        if(a<b){
                printf("ab未満\n");
        }else{
                printf("abより大きい\n");
        }
        if(a+b<100){
                printf("abの合計は100未満\n");
        }else if(a-b>0){
                printf("abの合計は100以上かつabの差は0より大きい\n");
        }else{
                printf("abの合計は100以上かつabの差は0以下\n");
        }
        return 0;
}

これは、abを入力させ、a==bであれば等しい、そうでなければ等しくないと表示。
a<bであればab未満、そうでなければabより大きいと表示。
a+b<100であれば、abの合計は100未満、そうでなくa-b>0であればabの合計は100以上かつ
abの差は0より大きい、そうでなければabの合計は100以上かつabの差は0以下と表示というものです。
この例ではif文、else-if文の終わりのブロックの直後にelse-if文、else文を書き始めていますが、
これはプログラムが見やすくなるということで私が好んで使用している記述です。
ですので、とくにこの記述で書かなければならないということはありません。
このようなことから、以降もこの記述を用います。

if文、else文、else-if文を多用すればあらゆる条件分岐が可能となりますが、
多用しすぎるとプログラムが見にくくなってしまうため、普通は、多用は避けた方が良いです。

C言語では値による場合分けが出来ます。それにはswitch文を用います。
if文では例1のように書くところを、switch文では例2のようにすっきりと書くことが出来ます。

1

#include <stdio.h>
int main(void){
    int a;
        scanf("%d",&a);
        if(a==1){
                printf("1\n");
        }else if(a==2){
                printf("2\n");
        }else if(a==3){
                printf("3\n");
        }
        return 0;
}

 2

#include <stdio.h>
int main(void){
    int a;
        scanf("%d",&a);
        switch(a){
                case 1:
                        printf("1\n");
                        break;
                case 2:
                        printf("2\n");
                        break;
                case 3:
                        printf("3\n");
                        break;
        }
        return 0;
}

 switch文は

switch(変数(整数値)){
        case 数値1:
                処理1;
                break;
        case 数値2:
                処理2:
                break;
}

と記述します。
条件式(変数)の値により、その値が数値1であれば処理1を、数値2であれば処理2を行うと言うものです。
処理の後に書いてあるbreakbreak文といい、プログラムがbreak文に来たとき、break文があるブロックを
抜け出すということを意味しています。
更にswitch文は以下の様に書くことも出来ます。

#include <stdio.h>
int main(void){
    int a;
        scanf("%d",&a);
        switch(a){
                case 1:
                case 2:
                        printf("1\n");
                        break;
                case 3:
                        printf("3\n");
                        break;
        }
        return 0;
}

これは、a12のときに1と表示されます。
つまり、ある数値とある数値との場合で同じ処理をさせたい場合に便利です。
このことより、break文がないとbreak文の次のcaseの処理も同じ処理とみなされてしまいます。

#include <stdio.h>
int main(void){
    int a;
        scanf("%d",&a);
        switch(a){
                case 1:
                        printf("1");
                case 2:
                        printf("2");
                case 3:
                        printf("3");
        }
        printf("\n")
        return 0;
}

これは、1の場合は1232の場合は233の場合は3と表示されてしまいます。
これまでswitch文について説明してきましたが、switch文は扱えるのは整数値のみであり、
条件式等は扱うことが出来ません。その部分についてはif文の方が優れていると言えます。
よって、整数値のみでの条件分岐の場合はswitch文を用いるようにした方がよいです。
また、もしもその整数がcase文のどれにも当てはまらない場合に処理を行いたいときにはdefault文を使用します。

#include <stdio.h>
int main(void){
    int a;
    scanf("%d",&a);
    switch(a){
            case 1:
                    printf("1");
                        break;
            case 2:
                    printf("2");
                        break;
            case 3:
                    printf("3");
                        break;
                default:
                        printf("不正な値が入力されました");
                        break;
    }
    printf("\n")
    return 0;
}

これは13の値が入力されなかったときに「不正な値が入力されました」と表示されます。
        何もしないプログラムのところで、
      return文の後に書かれたプログラムは実行されないが例外があると書きました。
       この例外とは、条件分岐を用いた際に、その中にreturn文が存在する場合です。
      そのreturn文が存在する条件分岐がじっこうされない場合はそれ以降のプログラムでも実行されます。

次に、条件演算子について説明します。
条件演算子は

条件式?1():2()

と記述します。これは、条件式が真であれば値1を、偽であれば値2をこの式の値とするというものです。
(
)と書いたのは、計算結果が値であれば式で書いてもよいと言うことです。

また、一般に、3項演算子と呼ばれることもあります。

#include <stdio.h>
int main(void){
    int a,b,c;
        scanf("%d",&a);
        scanf("%d",&b);
        c=a<b?a:b
        printf("%d\n",c);
        return 0;
}

この例では、abより小さければaを、そうでなければbcに代入してcの値を表示しています。
if文を用いるよりも簡潔に書けるために便利です。
上のプログラムを以下のように書きかえるとよりプログラムが簡潔に書けます。

#include <stdio.h>
int main(void){
    int a,b;
        scanf("%d",&a);
        scanf("%d",&b);
        printf("%d\n",a<b?a:b);
        return 0;
}

このプログラムでは、printf関数の普通であれば数値や変数を書くところに条件演算子を用いて書かれています。
このように記述すれば、cという変数を用いずに書くことが出来るので、便利です。
もしもこのプログラムをif文で書くならば

if(a<b){

        printf("%d\n",a);

}else{

        printf("%d\n",b);

}

というように、1行で済むところが4行になってしまいます。
このように書くのは行数も必要ですし、タイプするのにも時間がかかってしまいます。
よって、このような場合は条件演算子を用いた方がよいです。
条件演算子は、条件式は1つだけでなく、複数の条件式を持つことも出来ます。

条件式1?1:条件式2?2:3

このように記述した場合には、条件式1が真だった場合は値1を、
そうでない場合に、条件式2が真であれば値2を、そうでなければ値3をその式の値とします。
上記のように記述すれば、条件式はいくらでも追加することが出来ますので、
複雑な条件判断でも条件演算子を用いて記述することは可能です。
ですが、複雑すぎるとかえってプログラムが見にくくなるので、そのような場合は使用しないほうが良いです。