★分岐構造:条件の否定★


条件の否定は「!(ノット)」を使います。

否定するということは、どういう意味なのでしょうか。

例えば「成立している条件」を否定すると「不成立」になります。

逆に「成立していない条件」を否定すると「成立」になります。

まずは使い方を書きますので、「!」を使わないプログラムと「!」を使ったプログラムを比べてみてください。


<sample program 017-01>

#include <stdio.h>

int main(void)
{
    int a = 13;

    if (a > 10) {
        printf("OK\n");
    }
    else {
        printf("NG\n");
    }

    return 0;
}

<実行結果>

OK
続行するには何かキーを押してください・・・

これは、「!」を使っていません。

あまり、意味のないプログラムですが、変数aの中身が10より大きいですから、実行結果は「OK」と表示されます。

次に、「!」を使ったプログラムを書きます。


<sample program 017-02>

#include <stdio.h>

int main(void)
{
    int a = 13;

    if (!( a > 10 )) {
        printf("OK\n");
    }
    else {
        printf("NG\n");
    }

    return 0;
}

<実行結果>

NG
続行するには何かキーを押してください・・・

先ほどのプログラムの条件に括弧をつけて、条件の前に「!」を付けています。

実行結果は、「NG」となっています。

つまり、成立していないということです。

条件だけを見ると、「変数aの中身は10より大きい」ですから「成立している」のですが、「!」が付いているために、「不成立」になっています。

このように、条件の結果を逆転させるのが、「!(ノット)」なのです。


では、もう一つ例を書きます。

まずは、「!」を使わない例から、


<sample program 017-03>

#include <stdio.h>

int main(void)
{
    int a;

    scanf("%d", &a);

    if (a) {
        printf("OK\n");
    }
    else {
        printf("NG\n");
    }

    return 0;
}

<実行結果1>

5
OK
続行するには何かキーを押してください・・・

<実行結果2>

0
NG
続行するには何かキーを押してください・・・

<実行結果3>

-5
OK
続行するには何かキーを押してください・・・

覚えていますか?「条件」は結局、「0以外」であれば「成立」し、「0」であれば「不成立」となります。

では、次は「!」を使ってみます。


<sample program 017-04>

#include <stdio.h>

int main(void)
{
    int a;

    scanf("%d", &a);

    if (!a) {
        printf("OK\n");
    }
    else {
        printf("NG\n");
    }

    return 0;
}

<実行結果1>

5
NG
続行するには何かキーを押してください・・・

<実行結果2>

0
OK
続行するには何かキーを押してください・・・

<実行結果3>

-5
NG
続行するには何かキーを押してください・・・

「条件」に「!(ノット)」をつけると「条件」が「逆転」します。

上の例では、「0」であれば「成立」し、「0以外」であれば「不成立」となります。

実は、このような使い方は良くある使い方なのです。

C言語では、次の2つの書き方は同じ意味になります。

  if( a == 0 )

  if( !a )

上の方は、変数aの中身が「0」であれば「成立」します。

下の方は、変数aの中身が「0」であれば、本来は「不成立」ですが、「!」が付いているので、条件の結果が逆転し「成立」となります。

つまり、両方とも変数aの中身が「0」の時に「成立」するのです。

そして、「0」か「0以外」かという「条件」は頻繁に登場します。

良く使うのが、「関数」や「動的メモリ確保」、「ファイル」といったところで使います。

※これらの使い方は、もっとずっと後で出てきます。

1つだけ、意味のある?(結構無理やりですが・・・)プログラムを書いてみましょう。

まずは、「!」を使わないプログラムです。


<sample program 017-05>

#include <stdio.h>

int main(void)
{
    int a = 13;
    int b = 0;
    int c;

    c = a / b;

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

    return 0;
}

<実行結果>



エラーになりました・・・


なぜ、エラーになったのでしょうか?

コンパイル・ビルドは正常に行えたのに、実行した時にエラーが発生しました。

コンパイルエラーと実行時エラーの違いはこちらを見てください。

変数aの中身(13)を1で割った答えや、2で割った答えはすぐに求まると思いますが、0で割った答えはどうでしょう?

整数での計算において、0除算(ゼロディバイド)の答えは用意されていません

つまり「エラー」になります。

整数の割り算をプログラムする場合、この0除算を考慮する必要があります。


<sample program 017-06>

#include <stdio.h>

int main(void)
{
    int a = 13;
    int b = 0;
    int c;

    if (!b) {
        c = 0;
    }
    else {
        c = a / b;
    }

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

    return 0;
}

<実行結果>

0
続行するには何かキーを押してください・・・

除数が「0」の時にif文が「成立」し、結果に「0」を代入しています。

なぜ、結果に「0」を代入するのかというと、そのまま除算すると実行時エラーになるからです。

つまり、除数が「0」の時は割り算を行わないのです。

これは、無理やりな例ですが、後々「0」かどうかを判断することが増えてきますので、あくまでも例としてとらえてください。

無理やりというのは、if (b == 0) とはっきり書いた方が良い場合もあるからです。

上の例では、int型なので動作していますが、int型とdouble型では動作が異なります。

試しに、double型で0除算をやってみましょう。


<sample program 017-07>

#include <stdio.h>

int main(void)
{
    double a = 13;
    double b = 0;
    double c;

    c = a / b;

    printf("%f\n", c);

    return 0;
}

<実行結果>

1.#INF00
続行するには何かキーを押してください・・・

変な結果が表示されました。

整数と実数(小数)はデータの構造が違うと書きましたが、こういったところでも違いがあるようですね。

※ただし、コンパイラによって結果に違いがあるかもしれません。あくまでもVisual Studioでの結果です。


次へ

戻る

目次へ