C言語関係掲示板

過去ログ

No.1082 「&&」,「 || 」 の優先順位について

[戻る] [ホームページ]
No.14197

「&&」,「 || 」 の優先順位について
投稿者---selvid(2004/05/24 19:36:39)


C言語を学習し始めたばかりの超初心者です。
下のような条件文の場合「&&」の方が優先的に処理されると思うのです
が、(a==0 && (b==0 || c==0) )とせず「||」を優先させていないのに
「NO」と表示されてしまうのです。これはどうしてなのでしょう。
どなたかお教え頂けないでしょうか。よろしくお願い致します。

#include <stdio.h>  
int main(void)
{
    int a = 0;
    int b = 1;
    int c = 0;

    if(a==0 && b==0 || c==0) {  
        printf("NO\n");
    }   
    else {
        printf("OK\n");
    }

    return 0;
}



No.14198

Re:「&&」,「 || 」 の優先順位について
投稿者---NykR(2004/05/24 19:50:51)


>「NO」と表示されてしまうのです。これはどうしてなのでしょう。

c==0だからです。


No.14199

Re:「&&」,「 || 」 の優先順位について
投稿者---selvid(2004/05/24 20:17:41)


早速のお返事ありがとうございます。

>>「NO」と表示されてしまうのです。これはどうしてなのでしょう。
>
>c==0だからです。

ということは、
(a==0 && (b==0 || c==0) )の文中の「||」には( )をつけても意味が
無いということでしょうか。何か「&&」と「||」を使って「||」を
優先させて効果を発揮するような例文などはないものでしょうか?


No.14200

Re:「&&」,「 || 」 の優先順位について
投稿者---ぽこ(2004/05/24 20:37:59)


>ということは、
>(a==0 && (b==0 || c==0) )の文中の「||」には( )をつけても意味が
>無いということでしょうか。

意味があります。
括弧が無い場合、
a==0 && b==0が先に評価されて、
評価結果をzとすると、次に
z || c==0 が評価されます。(上記のプログラムだとzは偽です)

括弧がある場合、
b==0 || c==0が先に評価され、
その評価結果をyとすると、次に
a==0 && y が評価されます(上記プログラムだとyは真です)

>何か「&&」と「||」を使って「||」を
>優先させて効果を発揮するような例文などはないものでしょうか?

上記に掲載されたプログラムの場合、
a==0 && b==0 || c==0もa==0 && (b==0 || c==0)も
評価結果は真になります。

条件式中のa==0の部分をa==1に変えると、括弧の有り/無しで
評価結果が変わります。


No.14201

Re:「&&」,「 || 」 の優先順位について
投稿者---NykR(2004/05/24 20:38:47)


>>c==0だからです。
>
>ということは、
>(a==0 && (b==0 || c==0) )の文中の「||」には( )をつけても意味が
>無いということでしょうか。

そういうことではないです。

論理AND式や、論理OR式は、左側のオペランドから順に評価されます。つまり

a==0 && b==0 || c==0

という式では、まず && 演算子の左オペランドである a==0が評価されます。

で、a==0は真なのでこの式の値は1になります、

というわけで

1 && b==0 || c==0

となります。このとき &&演算子の左オペランドは0と比較して等しくないので、右側を評価しなければ、全体の値はわかりません。
こういうときに限り、b==0も評価されます。

で、b==0は偽なので、値は0です。

1 && 0 || c==0

&&演算子の結果の値は、両オペランドが0と比較してともにともに等しくない場合に限り1になります。
というわけで、式 1 && 0 の結果は(右のオペランドの値が0と比較して等しいので) 0 です。

0 || c==0

で、 ||演算子も &&演算子と同じように、左オペランドの値だけでは式全体の値を決定できない場合に限り、右オペランドを評価します。

できませんね。

というわけで、c==0を評価します、その値は1です。

0 || 1

||演算子の結果の値は、両オペランドを0と比較していずれか一方でも等しくない場合は1、両方とも等しいときは0です。

というわけで結局元の式の値は1になります。


No.14204

Re:「&&」,「 || 」 の優先順位について
投稿者---selvid(2004/05/24 20:54:03)


お二方とも、迅速かつご親切なレスをして頂きありがとうございました。
これからもっと勉強していかなければいけないと思いました。


No.14210

Re:「&&」,「 || 」 の優先順位について
投稿者---RAPT(2004/05/25 00:14:21)


参考までに。

&& → ×(乗算)
|| → +(加算)
に読み替えると、算数の考え方と同じことが分かるかと思います。
# 但し、演算結果は数値ではなく真偽値になりますが。

真=1(0以外)、偽=0と読み替えます。
  • 真 && 真 || 偽 → 1 * 1 + 0 == 1 → 真
    
  • 真 && 偽 || 偽 → 1 * 0 + 0 == 0 → 偽
    
  • 真 &&(真 || 偽)→ 1 *(1 + 0)== 1 → 真
    
  • 真 && 真 || 真 → 1 * 1 + 1 == 1 → 真
    
# 数式では 1 * 1 + 1 == 2 ですが、真偽値は0か0以外の値であり、
# ここでは、0か1としているので、答えは「1」となります。



No.14215

Re:「&&」,「 || 」 の優先順位について
投稿者---monkey(2004/05/25 07:23:07)


どのオペランドが実際に評価されるかを確かめるプログラムを書いてみました.
カッコの場所をいろいろ変えてみると,優先順位と短絡評価の仕組みがよく分かると思います.
#include <stdio.h>

int True( int n )
{
    printf( "%2d", n );
    return 1;
}

int False( int n )
{
    printf( "%2d", n );
    return 0;
}

int main()
{
    if( True(1) || False(2) && True(3) || True(4) && False(5) )
        printf( ":True\n" );
    else
        printf( ":False\n" );

    if( ( True(1) || False(2) ) && ( True(3) || True(4) ) && False(5) )
        printf( ":True\n" );
    else
        printf( ":False\n" );

    return 0;
}