条件の否定は「!(ノット)」を使います。
否定するということは、どういう意味なのでしょうか。
例えば「成立している条件」を否定すると「不成立」になります。
逆に「成立していない条件」を否定すると「成立」になります。
まずは使い方を書きますので、「!」を使わないプログラムと「!」を使ったプログラムを比べてみてください。
<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つだけ、意味のある?(結構無理やりですが・・・)プログラムを書いてみましょう。
まずは、「!」を使わないプログラムです。
#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での結果です。