論理演算子の取り扱いの注意

条件判定表記 意味
条件 && 条件

左右の条件が共に成立した場合だけ、全体を成立と判定します。
(左右の条件の結果がが共に0以外であれば結果を1にします)
(左の評価が0なら右の評価をせずに、全体の結果を不正立の0と演算します)

条件 || 条件

左右の条件のどちらかが成立すれば、全体を成立と判定します。
(左右の条件の結果がが共に0であれば結果を1にします)
(左の評価が1なら右の評価をせずに、全体の結果を不正立の1と演算します)

  ! 条件

右の条件が成立しないなら、全体を成立と判定します。
(右の条件を反転して判断します。)

&& のAND(アンド)演算子は、左式の評価が不成立なら、右式の評価をしない。

&& 演算子は、左式の評価が不成立なら、右式を判定するための実行を行いません。 左式の評価が不成立なら式全体を不成立と判定できるからです。
以下に配列 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]の記憶内容もアクセスしてしまいます。 その場合は実行エラーになります

|| のOR(オア)演算子は、左式の評価が成立するなら、右式の評価をしない。

|| 演算子は、&&演算子と逆で、左式の評価が成立すれば、右式を評価する実行をしません。 左式の評価が成立すれば、全体が成立すると判定できるからです。