アプリ版:「スタンプのみでお礼する」機能のリリースについて

【C言語】if文内の演算子の優先順位について

こんにちわ。初めて質問を投稿させて頂きます。
宜しくお願い致します。

【環境】
OS:Windows XP(SP3)
コンパイラ:Visual C++ 6.0
CPU:AMD Athlon X2 4200+

【質問】
私は下記のプログラムを実行しました
---------------------------------
【プログラム】
#include <stdio.h>

int main( void )
{
int i = 1;
int j = 2;
printf( "i = %d\n",i );
printf( "j = %d\n",j );
if( (i = 0) && (j = 200) == 200 ){
printf( "\n(1)-----------------------------\n" );
printf( "i = %d\n",i );
printf( "j = %d\n",j );
}
printf( "\n(2)-----------------------------\n" );
printf( "i = %d\n",i );
printf( "j = %d\n",j );
return 0;
}
【出力結果】
i = 1
j = 2

(2)-----------------------------
i = 0
j = 2 //(※)

---------------------------------

私は【出力結果】(2)のj = 2という出力結果(上記(※)の行)は
j = 200にならないとおかしいと思っております。
なぜなら、私は【プログラム】内のif文「if( (i = 0) && (j = 200) == 200 )」
の判定手順が下記の様になると考えているからです。

 (1)i = 0を実行
 (2)j = 200を実行
 (3)(i = 0)の判定実行
  →判定の結果「0」なので&&の右側の判定「(j = 200) == 200」
   を行うまでも無くif文全体の判定がFALSE。

しかし、実際は「j = 200」が実行されてないので、上記(2)と(3)の
判定手順が逆転している様に見えます。
C言語の優先順位を見ると「&&」や「==」よりも「()」の方が高いと
記憶してるので、(2)→(3)の順に実行されないとおかしいと思ってます。

しかし、私の予想した結果と実際の出力結果が異なるので私の演算子の優先順位
やif文内での判定手順の理解に間違いがあると考えています。

出来ましたらどの点が間違っているのかご教授願えませんでしょうか?

宜しくお願い申し上げます。

A 回答 (7件)

>#6さん



>(1)iに0を代入しますよ
>(2)jに200を代入しますよ
>(3)i=0で、j=200なら下のプログラムを実行しますよ

だから、違いますってば。

(1)iに0を代入する。
(2)i = 0という式を評価する。結果は0(C言語でいうところの偽)となる。
(3)&&以降を「評価しない」。

よって、jに200を代入することは「ありません」。
    • good
    • 0
この回答へのお礼

・お忙しい中、ご回答頂きありがとうございました!
私は、「()」演算子がどの様な条件下でも"必ず"「()」の中から
実行されるのだと思い込んでいました。その点が間違っている事
に気が付きました。
ありがとうございました。

お礼日時:2010/09/20 11:58

すでに他の方が答えてるので私は言わなくてもいいのかもしれませんが・・・



if( (i = 0) && (j = 200) == 200 )

この部分ですが、

(i = 0) && (j = 200) == 200

という条件を満たすなら下のプログラムを実行せよ
って命令ですよね?

手順としては

(1)iに0を代入しますよ
(2)jに200を代入しますよ
(3)i=0で、j=200なら下のプログラムを実行しますよ

という命令なので、もし命令を実行したいのであれば・・・




if( (i = 0) && (j = 200) == 200 ) 

この部分を

i=0;
j=200;
if( i == 0 && j == 200 ) 

こういう風に変えればプログラムを実行できると思いますよ?
    • good
    • 0
この回答へのお礼

・お忙しい中、ご回答頂きありがとうございました!
私の書き方が悪く、私の質問の内容が上手く伝わらなかったかもしれません(>_<)
ちょっと私が求めていた回答と異なりますが、参考にさせていただきます。
ありがとうございました。

お礼日時:2010/09/20 11:54

if文内に記述された代入式が評価よりも先に実行されると考えている部分が間違いです。



実際の動作の流れは、

if (A&&B) の形なのでまずAを評価する必要がある
Aは(i=0)なので、iに0を代入し0を評価する値とする
0は偽なので、Bは評価せずに終了する。

という形です。Bに書かれた(j=200)という代入式は、Bが評価された場合のみ実行されます。

この回答への補足

・お忙しい中、ご回答頂きありがとうございました!
私はC言語で「()」の演算子がついていればどんな条件下でも全て「()」の中から
絶対に実行されるんだと思い込んでいました。
if文(もしかしたら、if文以外の判定処理でも)の様な判定処理では「()」の
中から実行されるわけでなく判定処理から実行されるという事が理解できました。
ありがとうございました。

補足日時:2010/09/20 11:49
    • good
    • 0
この回答へのお礼

・お礼に書くべき内容を補足に書いてしまいました。
大変失礼致しました。

お礼日時:2010/09/20 11:59

こんにちは。



if( (i = 0) && (j = 200) == 200 )

という条件は

・変数 i に 0 を代入する
・結果 0 を返し、評価する
・0 なのでここで if 判定は「偽」とみなし、以下は実行されない

が正解だと思いますが、最初から何もこのようにわかりにくいコードを書かないことです。
何がしたいのか、もっとストレートに表現できませんか?
代入文の結果を評価に使えることは C では禁止されていませんが、
自分でも判断がつかないような表現をわざわざしないことです。

この回答への補足

・お忙しい中、ご回答頂きありがとうございました!

>最初から何もこのようにわかりにくいコードを書かないことです。
分かりました・・・。処理の内容を見直し、分かりやすいコードに
書き直してみます。

補足日時:2010/09/20 11:44
    • good
    • 0
この回答へのお礼

・お礼に書くべき内容を補足に書いてしまいました。
大変失礼致しました。

お礼日時:2010/09/20 12:04

>if( (i = 0) && (j = 200) == 200 )


( )は優先されています。ただこの場合は,(i=0)を評価した後,&& 以下がどうであろうと,もはや真にはならないので,(j = 200) == 200 は評価されません。(i=0)のあとの演算で真になる可能性のある演算子,たとえば"+"とかだったら,たとえ結果として偽になるとしても,(j = 200)も評価されると思います。無駄にならないようなコンパイラの仕様だと思います。

この回答への補足

・お忙しい中、ご回答頂きありがとうございました!
コンパイラの仕様ですか・・・。このような変なif文を記述するとコンパイラごとに
違った動きをする可能性があるかもしれないという事ですね・・・。
誰が見ても間違えないようなコードを書くように心がけます。

補足日時:2010/09/20 11:42
    • good
    • 0
この回答へのお礼

・お礼に書くべき内容を補足に書いてしまいました。
大変失礼致しました。

お礼日時:2010/09/20 12:04

> if( (i = 0) && (j = 200) == 200 )


このif文の判定式内で、最初に考えなければならないは「&&」と「==」の優先順位です。
a> 「(i = 0) && (j = 200)」 == 「200」
b> 「(i = 0)」 && 「(j = 200) == 200」
のどちらになるかでは、== の方が優先順位が高いので、bと解釈されます。
この段階では、括弧の優先順位を考えるような出番はありません。

そして、まず 「(i = 0)」 の評価を行い、その値が0なので、「(j = 200) == 200」の評価を行うことなく、結果の0が確定します。
    • good
    • 0
この回答へのお礼

・お忙しい中、ご回答頂きありがとうございました!
私の間違いはどんな条件下でも"常に必ず"「()」演算子の内容から
実行されるもんだと思い込んでいました。そのためj = 200になる
と解釈しておりました。
その間違いに気が付くことが出来ました。ありがとうございました。

お礼日時:2010/09/20 12:02

if文の後は、実行されているのではなく「条件」なので、i=0 かつ j=200 という「条件」の時と言う処理なので、if文の解釈自

体が間違って覚えていませんか?

この回答への補足

・お忙しい中、ご回答頂きありがとうございました!
もしかしたら、私のif文の解釈が間違ってるんだとおもいます・・・。

補足日時:2010/09/20 11:37
    • good
    • 0
この回答へのお礼

・お礼に書くべき内容を補足に書いてしまいました。
大変失礼致しました。

お礼日時:2010/09/20 12:00

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!