• ベストアンサー

!(否定)演算子について

!演算子の動きが知りたいです。 !0なら1になる !1なら0になる のは解るのですが !3など数値を入れた場合、0になるのはどの様な内部処理なのでしょうか? ビット演算 0011  ↓ 0 or 0 or 1 or 1  ↓  1  ↓  !1  ↓  0 上記と考えているのですが、アドバイスよろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • chie65535
  • ベストアンサー率43% (8520/19368)
回答No.3

>!0なら1になる 違います。 「!0なら非0になる」です。 「0でない値」と決まっているだけで、1になる保証はありません。0以外の何になるかは決まっていません。 なので「1になる筈」として1と比較すると「1とは異なる」と言う結果になる事があります。 >!1なら0になる 違います。 「!非0なら0になる」です。 非0は「0でないなら、何でもよい」ので、1でも2でも3でも65535でも2147483647でも構いません。 これを理解するには、bool型を理解しておく必要があります。 C++から導入された「bool型」は「trueかfalseの値を格納できる型」と定義されています。 そして「falseは0」「trueは0でない値」と定義されています。 「0でない値」は、1かも知れないし、2かも知れないし、-1かも知れないし、255かも知れません。「0でない」としか決まっていないのです。 なので「ある処理系ではtrueの実際の値は1なのに、別の処理系ではtrueの実際の値は-1になっている」って事も有り得ます。 >!3など数値を入れた場合、0になるのはどの様な内部処理なのでしょうか? 例えば bool f; f = !3; と書くと、以下のプログラムと同等の実行コードになります。 bool f; if (3 == 0) f = true else f = false; なお「!3」や「(3 == 0)」などは「常に同じ結果になる」ので、コンパイル時に最適化され、以下のプログラムと同等になります。 bool f; f = false;

abuhiro
質問者

お礼

アドバイスありがとうございます。 「0でない値」の部分が非常に参考になりました。 そう考えるとしっくりきます。 非常に学習になりました。

その他の回答 (5)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.6

・C において「真理値を返す演算子」が返すのは必ず 0 か 1 ・C++ において bool を int に変換すると false は 0, true は 1 になる (「NULL が 0 か」と同様「true が 1 で表現されている」というわけではないが) です>#3.

回答No.5

手元にあったJIS規格書(X 3010-1993)の記述: 6.3.3.3 単項演算子  論理演算子!の結果は,そのオペランドの値が0と比較して等しくない場合0とし,等しい場合1とする。結果の型は,intとする。式!Eは,(0==E)と等価とする。 回答No.2のとおりです。

  • chie65535
  • ベストアンサー率43% (8520/19368)
回答No.4

因みに、!演算子は、インテル系のCPUの命令コードで、以下のようになります。 MOV ECX,[メモリ] ; ECXレジスタに評価する値を持って来る XOR EAX,EAX ; EAXレジスタを0にする TST ECX ; ECXレジスタの値によってZフラグをセット BNE $+3 ; Zフラグが立ってないならINC EAXの次の命令にジャンプ INC EAX ; EAXをインクリメントして1にする MOV [メモリ],AL ; 結果をbool型変数のメモリに格納(bool型変数のサイズは1バイトと想定) インテル系のCPUでは、式の演算結果は「EAXレジスタに作られるのが基本」なので、上記命令コードを実行すると、EAXレジスタにtrueかfalseの値が作られ、それが変数用メモリに格納されます(但し、最適化を行った場合は、EAXレジスタに作られるとは限らない)

  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.2

「0なら1」、「0以外なら0」という動作しているだけかと。 …正しくは「真なら偽」「偽なら真」かと思われますが……。 # 0が偽、0以外が真…とか。

  • suzukikun
  • ベストアンサー率28% (372/1325)
回答No.1

否定演算子!はビット演算ではなく論理演算子です。 !true=false !false=true というものです。 Cでは「0でない」ものは論理演算子ではTrueなので「!3」はFalseとなり、内容を見ると0(false)になります。 Cのビット演算子は~(チルダ)です。

関連するQ&A

  • チェックボックスをビット演算子で処理したい

    チェックボックスをビット演算子で処理したいのですが、DBに格納した数値をビット演算子で処理する方法がわかりません。 たとえば、北海道から沖縄までのチェックボックスを作成してそれぞれに 1,2,4,8,16,32・・・とvalueを持たせます。 DBには数値の和を入れておきます。 その値を分解してチェックボックスをcheckedにしたいです。 ちょっとわからなくなってしまって。 教えてください、。よろしくお願いします。

    • ベストアンサー
    • PHP
  • 演算子を使わない演算

    はじめまして、ヨロシクお願いします。 早速ですが、私は今「入力された数値を7で割った値を表示しろ」という問題に取り組んでいます。これには次の条件があります。 (1)演算子の/を使ってはいけない。 (2)繰り返し処理を使ってはならない。 という縛りがある上で計算をしたいと思っているのですが、なかなかうまくいきません。何かいい方法はないでしょうか。 よろしくお願いします。

    • ベストアンサー
    • Java
  • ビット演算を学びたい

    a &= 2; a |= 2; a ^= 2; a ~= 2; a <<=2; a >>=2; みたいな感じでビット演算が使われているソースを 良く見るのですが、いまいちビット演算で何をしているのかが 分かりません。 参考書などには文字通りビットをいじるような旨のことが書いてあります。 (こちらにも同じようなことが http://www9.plala.or.jp/sgwr-t/c/sec14.html) こういうので何となくは分かるのですが、 実際にこれを何に使えるか、実践ではどのように使うのかが なかなか見えてきません。 このビット演算を私のような者でも実際のプログラムで使いこなせるように なれるようなサイトや書籍の提示、あるいはサンプルのプログラムなどで ご指導いただけたらと思います。

  • 浮動小数点演算と固定小数点演算の使い分けについて

    解説書などには、「浮動小数点は3.14E0の形」や「固定小数点は3.14」などと説明されています。 では、例えば、ごく一般的な32ビットマシンで「3.14 * 45.6」という命令を書いたときに演算されるのは浮動小数点演算なのか、固定小数点演算なのかがわかりません。例えばIntelのx86CPUは、内部にFPUを持っているそうですが、この場合は「3.14 * 45.6」は、内部では必ず浮動小数点演算になっているということなのでしょうか? 「3.14 * 45.6」を「3.14E0 * 4.56E1」と書いた場合にしか浮動小数点演算されないということではないと思っているのですが、実際の浮動小数点演算と固定小数点演算の内部的な切り替えがわかりません。 理解が足りなくて、おかしな質問になっていましたら、その点もご指摘いただければうれしいです。

  • 論理演算

    ビットの判定するために次のコードをしました。 if ( A And 2 = 2 ) or ( A And 4 = 4 ) Then ~ Aの論理積の結果が2か4ならばThen以下の処理の中に入っていってもらいたいのです。 ところが上記のコードでは演算式になってしまっているようで、 結果的にAが0以外ならば全てThenに入ってしまうザルコードになってしまいました。 散々つつきまわって以下のように( ) で括ればいいことが分かりました。 if (( A And 2 ) = 2 ) or (( A And 4 ) = 4 ) Then ~ ( )で括ればいいというのは分かりましたが、理由はさっぱり分かりません。 一番最初に書いたコードでも正常に見えるからです。 納得がいきませんので、どなたか説明よろしくお願い致します。

  • 2進数データのビット演算

    vb.netにて 0と1からなる2進数で記録した2つの値をビット演算したいと思っております。 Convert.ToInt32("1111101000", 2) などを使って、一度数値に変換して演算すれば、計算可能なことはわかったのですが、計算に利用したいデータが2進数で1000桁ほどあります。桁数が多い場合、Convert.ToInt32ではエラーが出て実行できません。 無数に長い2進数のデータをビット演算するにはどうすればよろしいでしょうか。 ご存知の方、ご教授よろしくお願いいたします。

  • 論理演算子について

    論理演算に使う「or」なんですが、制御構文ifと組み合わせて以下のような使い方をしてみました。 $data01='aaa'; $data02='あああ'; $data03='test'; if ($data01 =~ m/aaa/ or $data02 =~ m/あああ/ or &data03 =~ m/test/){ 特定の処理; } このorによる論理演算ははどこまでできるのでしょうか? 上のスクリプトは問題なく動いていますが、ちょっと不安です。 専門書を見ても、orによる論理演算は<条件1 or 条件2>としか書いてなく <条件1 or 条件2 or 条件3 or ・・・>と書いても大丈夫なのでしょうか? いくつもの比較はorを使わないほうがよろしいとは思うんですが、このorが便利なのでこれで済むなら使いたいと思います。

  • 論理演算、ビット演算

    C言語仕様上、真/偽は(Not0/0)であることは理解しています。また、処理順序から、論理演算とビット演算では評価対象の範囲が違うことも知っているつもりです。 その上で質問させていただきます。 お手数ですが、お解りになる方は教えていただけると助かります。 例えば、 i=0,j=0である場合 ( (i == 0) && (j == 0) )は真であると思いますが、 ( (i == 0) & (j == 0) )は規定されているでしょうか。 また、( (i == 0) | (j == 0) )は真となることが(理論上)保証されているように思えますが、問題ないでしょうか。 以上、よろしくお願いいたします。

  • php と C# の ビット演算

    PHPでビット演算をしていますが、 PHPでたとえば、 c = a >> b でビット演算した値と、 C#で演算した値と aの値を大きくした場合、 4000000000以上? は結果が違ってきます。 C#とPHPではビット演算のアルゴリズムが違うのでしょうか? よろしくお願いします。

    • ベストアンサー
    • PHP
  • 演算子について

    2進数の文字列を数値に変換する処理の中で、 for(i= 0; binary[i] != 0; i++) { value <<= 1; value |= binary[i] - '0'; } value <<= 1; はvalueを左へ1ビットシフトするということがわかりますが、 次の value |= binary[i] - '0'; は、 書き直すと、 value = value | binary[i] - '0'; となり、『|』ではvalueとbianary[i]をORすることがわかりますが、その次の『 - '0' 』では何を行っているのかよくわかりません。 どなたかお解りの方、解説のほうお願いします。

専門家に質問してみよう