int型変数の評価

[戻る]
2005/05/24(火) 07:22:31
n1=15,n2=7,n3=0という前提で。

!(n2==n3)を評価した値は1になるそうなんですが、それはなぜですか?
n3しか0ではないのに、なぜなんでしょう?

KING・王 2005/05/24(火) 08:05:26
(n2==n3)はn2とn3の値が異なるため、偽となり0と評価されます。
で、呂さんの記述されているコードでは、(n2==n3)の前に'!'が記述されているため、
(n2==n3)の真偽が反転されます。
よって、!(n2==n3)は真と評価されます。

一般的に、真は1となっているようですが、これは環境依存であり、
真は0でないことは保証されていますが、1であることは保証されていなかったと思います。

厳密には、
> !(n2==n3)を評価した値は1になる
と考えるのは危険です。
if( (!(n2==n3)) == 1 )
というようなコードが有った場合など、問題になる可能性がありますので。

tetrapod 2005/05/24(火) 08:44:24
C では「条件式」の結果は常に int 型で、その値は 1 (条件が真) または 0 (条件が偽) の
どちらかです。

C++ では「条件式」の結果は常に bool 型で、その値は true (条件が真) または false (条
件が偽) のどちらかです。
そして汎整数変換により true は 1 に、 false は 0 に、変換されます。

よって !(n2==n3) という「式の値」は常に 1(true) です。それ以外ありえません。

「条件式の値」ではなく「真偽判定の条件」ならば 0 以外が真となります。
ごっちゃにしないでください。

2005/05/24(火) 23:03:01
お二方、どうもアドバイスありがとうございます。

ところでKING・王さんに質問です。

>if( (!(n2==n3)) == 1 )
>というようなコードが有った場合など、問題になる可能性がありますので。
これは、具体的にどういう問題があるのでしょうか?
結局は、ここでの問題文と同じことを言ってるわけじゃないんですか?

まきじ 2005/05/24(火) 23:17:28
>if( (!(n2==n3)) == 1 )

n2 == n3 が 偽の時は、必ず 0 ですが、!0 は、1 とは
限らない、0 以外の数値になります

まきじ 2005/05/24(火) 23:23:04
言葉たらずですね(^^;

よって、!(n2 == n3) の戻り値は 0 以外なので、== 1 と判定してしまうと、
n2 != n3 なのに、if 文が成り立たない時があります。

reshia 2005/05/24(火) 23:49:38
別の角度から。

・「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
にありますので、参考にしてください。

YuO [E-Mail] 2005/05/25(水) 00:27:21
> 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さんの記述をちゃんと読み返して下さいね。

まきじ 2005/05/25(水) 01:32:04
色々と調べた結果、YuOさん、tetrapodさんの
仰ってる意味が理解できました。

>!(n2==n3) という「式の値」は常に 1
というのも、納得いきました。

== , && , || , ! などの戻り値は、0 か 1 ですが、

if文の条件の部分は、偽にするなら 0 で、
真にするなら、if(100) などでも、真になるので
非0 ということですね。

私が勉強不足でした(^^;

KING・王 2005/05/25(水) 12:29:02
tetrapod様

> 「条件式の値」ではなく「真偽判定の条件」ならば 0 以外が真となります。
> ごっちゃにしないでください。

申し訳ございません。
このあたりの区別ができていませんでした。

> if( (!(n2==n3)) == 1 )

に関しては、BOOLが戻り値の関数の結果をTRUEと==で比較するのはダメである、
ということと勘違いしていました。

# WindowsのAPIの中にも、戻り値がBOOL型のAPIで、FALSEでもTRUEでもない値を返す
# APIが存在すると言う話を耳にしたことがありましたので。。。

Ban 2005/05/25(水) 13:08:12
> # WindowsのAPIの中にも、戻り値がBOOL型のAPIで、FALSEでもTRUEでもない値を返す
> # APIが存在すると言う話を耳にしたことがありましたので。。。

# 確かにありますね。
# でも、MSDN を読むと「TRUE を返す」とも「FALSE を返す」とも書いてなくて、
# ちゃんと「0以外の値が返ります」とか「0 が返ります」って書いてあるんですよね。
# 戻り値の型が BOOL になってる API でも、MSDN で TRUE / FALSE を返すと
# 書いてあるものはいまだ見たことがありません。

YuO [E-Mail] 2005/05/25(水) 13:48:48
> # 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

古いスレッドには追加発言できません。