【C言語】
&演算子と&&演算子の違いは
短絡評価の扱い


■ビット演算と論理演算の違い

#include <stdio.h>
int main(void){
    int bit =  0xFF00 & 0xFF; //⇒ 0x00=ゼロ=偽
    if(bit)  {
        printf("真:%x\n",bit);
    } else {
        printf("偽:%x\n",bit);
    }  
    
    int log = 0xFF00 && 0xFF; //⇒ 非ゼロ&&非ゼロ=真&&真=真 
    if(log)  {
        printf("真:%x\n",log);
    } else {
        printf("偽:%x\n",log);
    }  
}

●ビット演算
0xFF00 & 0xFF

0x00

ゼロ


●論理演算
0xFF00 && 0xFF

非ゼロ&&非ゼロ

真&&真

●実行結果

./a.out
偽:0
真:1

短絡評価は、ビット演算無し論理演算有り

#include <stdio.h>
#include <stdbool.h>
bool    True(void){ 
    printf("%s⇒",__func__); 
    return  true;   
}
bool    False(void){
    printf("%s⇒",__func__); 
    return  false;  
}
int main(void){
    if(False() & True())    puts("結果⇒真");
    else                    puts("結果⇒偽");
      
    if(False() && True())   puts("結果⇒真");
    else                    puts("結果⇒偽");
}

●False() & True()

&はビット演算子なので両辺を簡略化すると
0&1=0=偽となり
if(偽)は成立しないのでelse節 が表示される。

●False() && True()

&&は論理演算子なので両辺を簡略化すると
0&&1=ゼロ&&非ゼロ=偽&&真=偽となる。

第一条件が成立しなかった時点で、
この条件式全体が成立しない事が確定するので
第二条件を評価する必要がない
すなわちTrue()関数は呼ばれない。

これを短絡評価(ショートサーキット動作)と
言う。


●実行結果

./a.out
False⇒True⇒結果⇒偽
False⇒結果⇒偽

Segmentation fault (コアダンプ)するかも

#include <stdio.h>
void bit_and(char  *p){
    printf("%s⇒",__func__);
    if ((p != NULL) & (p[0] != '\0'))   //ビット演算子 
        puts(p) ; 
    else
        puts("nop");
} 
void log_and(char  *p){
    printf("%s⇒",__func__);
    if ((p != NULL) && (p[0] != '\0'))  //論理演算子   
        puts(p) ; 
    else
        puts("nop");
} 
int main(void){
    log_and("ABC");
    log_and(NULL);
    bit_and("DEF");
    bit_and(NULL);
}

論理演算&&を使用すべきところで
ビット演算&を使用して
短絡評価が行われずコアダンプしてしまう例です。

●実行結果

./a.out
log_and⇒ABC
log_and⇒nop
bit_and⇒DEF
Segmentation fault (コアダンプ)

未定義動作なのでコアダンプするとは限りませんが。。。。

参考:

EXP02-C. 論理 AND 演算子および論理 OR 演算子のショートサーキット動作について注意する

https://www.jpcert.or.jp/sc-rules/c-exp02-c.html