5.2 if

例えば、以下のようなコードがあったとします。

#include<iostream>
int main()
{
    int a = 10,b = 20;
    std::cout << "aとbは等しいです" << std::endl;
    std::cout << "aとbは等しくないです" << std::endl;
}

これを実行するとこのように出力されます。

aとbは等しいです
aとbは等しくないです

abも処理させる事なく"aとbは等しいです""aとbは等しくないです"という文字列を出力しろとだけ書いているのですから、この出力結果は当然と言えますね。しかしabが同じ値であれば"aとbは等しいです"と出力し、そうでなければ"aとbは等しくないです"と出力したいものです。結論から言えば、以下のように書きます。

#include<iostream>
int main()
{
    int a=10,b=20;
    if(a==b){
        std::cout << "aとbは等しいです" << std::endl;
    }else{
        std::cout << "aとbは等しくないです" << std::endl;
    }
}

実行結果は以下となります。

aとbは等しくないです

ifelseが出てきました。1つ1つ解説していきます。まず、

if( 何かしらの演算式 ){ 処理A }

と書く事で、何かしらの演算式0falseでない場合、処理Aが実行されます。上記のコードの場合、a == bという演算は、falseであるので、aとbは等しいですという文字列は出力されません。

else{ 処理B }とはなんでしょう。これは、それ以外といった意味で何かしらの演算式0falseであった場合、処理Bを実行するという意味です。上記のコードの場合、a == bという演算は、falseであるので、「aとbは等しくないです」という文字列が出力されます。全体の文法を表すと以下のようになります。

if( 何かしらの演算式I ){ 処理A }
else if( Iがfalseであった場合の条件式II ){ 処理B }
else { I、IIともにfalseであった場合の処理 }

...これだけだと中々馴染まないので、いくつか例題を上げる事としましょう。

#include<iostream>
int main()
{
    int a = 20;
    if(a == 10){
        std::cout << "aは10です" << std::endl;
    }else if(a == 20){
        std::cout << "aは20です" << std::endl;
    }else{
        std::cout << "aは10でも20でもないです" << std::endl;
    }
}

実行結果は以下となります。

aは20です

if文部分を一つ一つ説明していきますね。まずif(a == 10){という行ではaが10であるかどうか演算させています。この場合結果はfalseですので、aは10ですは出力されません。次にelse if(a == 20){という部分では、aが20であるかどうか演算させています。この場合結果はtrueですので、aは20ですが出力されます。}else{は、その前にあるif(a == 10){}else if(a == 20){のどちらの演算結果もfalseである場合のみ実行されますので、aは10でも20でもないですと出力されませんし、処理すら到達しません。

では、以下のif文の処理の違いはなんでしょうか。

#include<iostream>
int main()
{
    int a = 10;
    if(a == 10){
        std::cout << "aは10です" << std::endl;
    }else if(a == 10){
        std::cout << "aは10です(2回目)" << std::endl;
    }

    if(a == 10){
        std::cout << "aは10です(3回目)" << std::endl;
    }if(a == 10){
        std::cout << "aは10です(4回目)" << std::endl;
    }
}

実行結果は以下となります。

aは10です
aは10です(3回目)
aは10です(4回目)

2回目が実行されていません。その訳はelse ifが使われている事にあります。else ifの前にある、if(a == 10)falseであった場合のみ、else if文が処理されるので、今回の場合はtrueですから、処理はされないのです。3回目と4回目は、ただif文が連続的に記述されているだけですから、どちらも処理が行われます。

では、次の例題にいきましょう。

#include<iostream>
int main()
{
    int a[5];
    if( sizeof(a) / sizeof(a[0]) == 5 ){
        std::cout << "aの要素数は5です。" << std::endl;
    }else{
        std::cout << "aの要素数は5ではありません。\n" << sizeof(a) / sizeof(a[0]) << "です。" << std::endl;
    }
}

実行結果は以下となります。

aの要素数は5です。

少し複雑になってきました。一つずつ説明していきます。まず、if式内のsizeof(a)部分で、配列をsizeof演算子に渡しています。このようにして渡した場合、sizeof演算子は配列全体のバイト数を演算します。つまり上記コードのsizeof(a)では20という数値を得る事ができています。それに対して配列aの一つ分の要素(上記コードではa[0]を用いてますね)で除算しています。全体のサイズを1つ分のサイズで割る事で何が得られるでしょうか。そうです、要素数を得る事ができるのです。つまり、

sizeof(a) / sizeof(a[0]) == 5

とは、配列aの要素数が5である場合trueとなり、そうでなければfalseとなります。この場合、冒頭でint a[5];と宣言されていますので、上記の式はtrueとなり、「aの要素数は5です」が出力されます。 それでは、最後の例題です。

#include<iostream>
int main()
{
    unsigned short int i[10];
    float f[10];
    if(sizeof(i) / sizeof(i[0]) == sizeof(f) / sizeof(f[0]))
        std::cout << "二つの要素数は等しいです。" << std::endl;
    else
        std::cout<< "二つの要素数は等しくないです。" << std::endl;
}

実行結果は以下となります。

二つの要素数は等しいです。

int型の配列ifloat型の配列fの要素数をそれぞれ割り出し照合しています。しかしif式で先ほどまで記述されていた{}が見受けられませんね。実は、一文までであれば、{}を省略して記述して良い事となっているのです。一文まで、というのがとても重要です。

#include<iostream>
int main()
{
    unsigned short int i[5];
    if(sizeof(i) / sizeof(i[0]) == 10)
        std::cout << "変数iの要素数は";
        std::cout << "10です。" << std::endl;
}

実行結果は以下となります。

10です。

配列iの要素数は5ですが、なぜか「10です。」とだけ出力されていますね。何故ならば、このコードは下記コードと同じ意味だからです。

#include<iostream>
int main()
{
    unsigned short int i[5];
    if(sizeof(i) / sizeof(i[0]) == 10){
        std::cout << "変数iの要素数は";
    }
    std::cout << "10です。" << std::endl;
}

このように、{}を省いた記述はその式の次の一文までを対象として含みます。慣れるまでは、{}を記述した方が無難かもしれません。