条件判定表記 | 意味 |
---|---|
条件 && 条件 | 左右の条件が共に成立した場合だけ、全体を成立と判定します。 |
条件 || 条件 | 左右の条件のどちらかが成立すれば、全体を成立と判定します。 |
! 条件 | 右の条件が成立しないなら、全体を成立と判定します。 |
&& 演算子は、左式の評価が不成立なら、右式を判定するための実行を行いません。
左式の評価が不成立なら式全体を不成立と判定できるからです。
以下に配列 iarray から、変数vのデータを探すプログラムを示します。
#include <stdio.h> #define ISIZE 5 /* 配列の要素数 */ int iarray[ISIZE] = {10,20,30,40,50 }; /* データを記憶する配列 */ int icount =5; /* 上記データ個数 */ main() { int idx = 0; /* 探し始める位置 */ int v = 99; /* 探すデータ */ while(idx < icount){/* 配列の中を探す繰り返し */ if(iarray[idx] == v ) break; /* 一致したら繰り返しを終える */ idx++; } if( idx < icount ) { printf("%dの位置にあります\n", idx);/* 見つかった */ } else { printf("見つかりません\n") ;/* 見つからない */ } }
上記は、&&を使うと次のように書けます。上と下のプログラムは全く同じ動作になります。
#include <stdio.h> #define ISIZE 5 /* 配列の要素数 */ int iarray[ISIZE] = {10,20,30,40,50 }; /* データを記憶する配列 */ int icount =5; /* 上記データ個数 */ main() { int idx = 0; /* 探し始める位置 */ int v = 99; /* 探すデータ */ while(idx < icount && iarray[idx] != v ){/* 配列の中を探す繰り返し */ idx++; } if( idx < icount ) { printf("%dの位置にあります\n", idx);/* 見つかった */ } else { printf("見つかりません\n") ;/* 見つからない */ } }
上記で着目すべき点は、idx < icount を先に判定している所です。
これが成立しない場合、iarray[idx] != v を評価する実行をしないことが大事です。
つまりデータが見つからない場合でも、記憶域として存在しないiarray[5]の記憶内容をアクセスしないわけです。
これは、左の評価が不成立なら、右の評価をしないという&& 演算子の仕様により可能なのです。
この順番を変えた次のプログラムは間違いです。
#include <stdio.h> #define ISIZE 5 /* 配列の要素数 */ int iarray[ISIZE] = {10,20,30,40,50 }; /* データを記憶する配列 */ int icount =5; /* 上記データ個数 */ main() { int idx = 0; /* 探し始める位置 */ int v = 99; /* 探すデータ */ while(iarray[idx] != v && idx < icount ){/* 配列の中を探す繰り返し */ idx++; } if( idx < icount ) { printf("%dの位置にあります\n", idx);/* 見つかった */ } else { printf("見つかりません\n") ;/* 見つからない */ } }
上記の場合、先にiarray[idx] != v を判定しています。 つまりデータが見つからない場合、記憶域として存在しないiarray[5]の記憶内容もアクセスしてしまいます。 その場合は実行エラーになります。
|| 演算子は、&&演算子と逆で、左式の評価が成立すれば、右式を評価する実行をしません。 左式の評価が成立すれば、全体が成立すると判定できるからです。