第2章 近道

 今回は、条件文についてのお話です。第3部なので、こういうともすれば隅に追いやられてしまうようなものにも光を当ててあげましょう。


 さて、今回の要点です。


 では、いってみましょう。


 さて、次の命題が真か偽かを考えてみて下さい。

命題「鳥は人間であり、かつ、虫である」

 って、はっきり言って人をバカにしていますね。もちろん、偽ですね。

 さて、あなたはどの時点で偽と判断しましたか? おそらく「かつ」の出てきた時点ではないでしょうか?

 「鳥は人間であり」ということからして偽です。ここに「または」が来れば次の条件も確かめないといけませんが、「かつ」が来ている時点でもう真にはなりえませんね。

 こういった判断はC/C++言語でも行われています。条件文が真か偽かが途中で分かったら、もうあとの条件は判定しないのです。これをショートサーキットと言います。

 このことは時間の節約になるので、ショートサーキットを行うのも当然のことと思うことでしょう。しかし、ショートサーキットを忘れたがために起こるバグも存在します。条件文の中に関数を入れてあっても、その関数が必ず呼ばれるとは限らないということで起こるバグです。途中で条件文の結果が分かったがために、関数を使用している条件が無視されることがあるのです。

 また、逆にショートサーキットの有効利用法なども存在します。関数が無視されることを利用してやるということです。


 まぁ、何はともあれショートサーキットを実感してみて下さい。

プログラム実行結果
// SC1.cpp
#include <iostream.h>

bool Input(double& value)
{
    cout << "数値を入力して下さい > " << flush;
    cin >> value;

    return value != 0;
}

int main()
{
    double a, b;

    while(Input(a) && Input(b))
    {
        cout << "a / b = " << a / b << endl;
        cout << "b / a = " << b / a << endl;
    }

    return 0;
}
数値を入力して下さい > 3.14
数値を入力して下さい > 1592
a / b = 0.00197236
b / a = 507.006
数値を入力して下さい > 2.718
数値を入力して下さい > 0.0028
a / b = 970.714
b / a = 0.00103017
数値を入力して下さい > 0

 このプログラムは、値を2つ入力して、お互いをもう片方で割った数を出力するプログラムです。

 割り算をするのですから、どちらとも0であっては困ります。なので、どちらかに0を入力するとプログラムを終了するようにします。

 先ず、入力は1つの関数 Input で済ませてしまうことにします。この関数は double 型の参照を引数にとっています。ここに変数を渡し、これが0かどうかを戻り値で表します。0の時は偽、0以外の時は真です。

 初めの方の Input で0が入力されると、次の Input を実行する必要はありません。簡単に考えると

while(1)
{
    if(!Input(a))
        break;
    if(!Input(b))
        break;

    ... 表示 ...
}

となるのですが、ここでショートサーキットが利用できます。

while(Input(a) && Input(b))

 先ず、初めの Input(a) が実行されます。このとき0が入力されると偽が返ってきます。あぁ、これは初めに話した命題と同じですね。初めの条件が偽と判断され、次に「かつ」があります。全く同じです。つまり、さっき考えたように、これはもう偽にしかなりえません。

 こうなると、次の Input(b) を実行することなく while 文は終了してしまいます。希望通りの動作になってくれました。


 さて、初めの Input(a) で0以外の値が入力されると、真が返ってきます。すると、まだ条件文を判定する必要があります。なぜなら、次の条件が真の時は全体は真になり、次の条件が偽の時は全体は偽になる、つまり、まだ条件文の結果が分からないからです。

 すると、ここでやっと Input(b) が実行されるわけです。ここで0以外の値を入力すれば条件文は真となり、while 文の実行文を実行します。ここで0を入力すれば条件文は偽となり、while 文は終了します。


 このように、ショートサーキットはプログラムの流れに重要な影響を与えることがあるのです。


 さて、今回の話も終わりましたので、要点を振り返ってみましょう。


 それでは、また次回で会いましょう。


第1章 シノニムの定義 | 第3章 コンパイル済

Last update was done on 2000.8.2

この講座の著作権はロベールが保有しています