n1=15,n2=7,n3=0という前提で。
!(n2==n3)を評価した値は1になるそうなんですが、それはなぜですか?
n3しか0ではないのに、なぜなんでしょう?
(n2==n3)はn2とn3の値が異なるため、偽となり0と評価されます。
で、呂さんの記述されているコードでは、(n2==n3)の前に'!'が記述されているため、
(n2==n3)の真偽が反転されます。
よって、!(n2==n3)は真と評価されます。
一般的に、真は1となっているようですが、これは環境依存であり、
真は0でないことは保証されていますが、1であることは保証されていなかったと思います。
厳密には、
> !(n2==n3)を評価した値は1になる
と考えるのは危険です。
if( (!(n2==n3)) == 1 )
というようなコードが有った場合など、問題になる可能性がありますので。
C では「条件式」の結果は常に int 型で、その値は 1 (条件が真) または 0 (条件が偽) の
どちらかです。
C++ では「条件式」の結果は常に bool 型で、その値は true (条件が真) または false (条
件が偽) のどちらかです。
そして汎整数変換により true は 1 に、 false は 0 に、変換されます。
よって !(n2==n3) という「式の値」は常に 1(true) です。それ以外ありえません。
「条件式の値」ではなく「真偽判定の条件」ならば 0 以外が真となります。
ごっちゃにしないでください。
お二方、どうもアドバイスありがとうございます。
ところでKING・王さんに質問です。
>if( (!(n2==n3)) == 1 )
>というようなコードが有った場合など、問題になる可能性がありますので。
これは、具体的にどういう問題があるのでしょうか?
結局は、ここでの問題文と同じことを言ってるわけじゃないんですか?
>if( (!(n2==n3)) == 1 )
n2 == n3 が 偽の時は、必ず 0 ですが、!0 は、1 とは
限らない、0 以外の数値になります
言葉たらずですね(^^;
よって、!(n2 == n3) の戻り値は 0 以外なので、== 1 と判定してしまうと、
n2 != n3 なのに、if 文が成り立たない時があります。
別の角度から。
・「n2==n3」は n2 と n3 が同じ値なら真、違うなら偽
n2=7,n3=0の場合、偽ですね
・「!(n2==n3)」は、まず普通の算数と同じように括弧の中が優先されて、その後に「!」
が行われる
括弧の中は、偽でした。その後に、「!」がされます。
「!」は否定(NOT)ですから、偽の反対は、真になります。
また、「!(n2==n3)」は、「n2 != n3」と同じことです。
全体を否定するのも、等号を否定するのも、この場合同じことです。
でtetrapodさんがおっしゃっておられるように、
>C では「条件式」の結果は常に int 型で、
>その値は 1 (条件が真)または 0 (条件が偽) のどちらかです。
なのですね。
あと
>if( (!(n2==n3)) == 1 )
は、ifの条件式に限らず、C言語の条件式は、0が偽として扱われ、
真というのは、偽以外、つまり0以外ならなんでも良いとなっています。
そして、このようなif文の書き方による弊害は、
関数の返り値でtrue、falseを判定する場合なんかに、よく出ます。
詳しくは、C Magazineホームページ「プログラミングの禁じ手Web版 C言語編」
http://www.cmagazine.jp/src/kinjite/c/index.html
にありますので、参考にしてください。
> n2 == n3 が 偽の時は、必ず 0 ですが、!0 は、1 とは
> 限らない、0 以外の数値になります
!0は定義により常に1です。
# 定義:ISO/IEC 9899:1999 6.5.3.3 Paragraph 5
故に,
> if( (!(n2==n3)) == 1 )
は,
if (n2 != n3)
と等価になります。
tetrapodさんの記述をちゃんと読み返して下さいね。
色々と調べた結果、YuOさん、tetrapodさんの
仰ってる意味が理解できました。
>!(n2==n3) という「式の値」は常に 1
というのも、納得いきました。
== , && , || , ! などの戻り値は、0 か 1 ですが、
if文の条件の部分は、偽にするなら 0 で、
真にするなら、if(100) などでも、真になるので
非0 ということですね。
私が勉強不足でした(^^;
tetrapod様
> 「条件式の値」ではなく「真偽判定の条件」ならば 0 以外が真となります。
> ごっちゃにしないでください。
申し訳ございません。
このあたりの区別ができていませんでした。
> if( (!(n2==n3)) == 1 )
に関しては、BOOLが戻り値の関数の結果をTRUEと==で比較するのはダメである、
ということと勘違いしていました。
# WindowsのAPIの中にも、戻り値がBOOL型のAPIで、FALSEでもTRUEでもない値を返す
# APIが存在すると言う話を耳にしたことがありましたので。。。
> # WindowsのAPIの中にも、戻り値がBOOL型のAPIで、FALSEでもTRUEでもない値を返す
> # APIが存在すると言う話を耳にしたことがありましたので。。。
# 確かにありますね。
# でも、MSDN を読むと「TRUE を返す」とも「FALSE を返す」とも書いてなくて、
# ちゃんと「0以外の値が返ります」とか「0 が返ります」って書いてあるんですよね。
# 戻り値の型が BOOL になってる API でも、MSDN で TRUE / FALSE を返すと
# 書いてあるものはいまだ見たことがありません。
> # WindowsのAPIの中にも、戻り値がBOOL型のAPIで、FALSEでもTRUEでもない値を返す
> # APIが存在すると言う話を耳にしたことがありましたので。。。
GetMessage APIなんかが該当しますね。
http://msdn.microsoft.com/library/en-us/winui/winui/windowsuserinterface/
windowing/messagesandmessagequeues/messagesandmessagequeuesreference/
messagesandmessagequeuesfunctions/getmessage.asp