web-dev-qa-db-ja.com

これは何ですか!オペレーター?

このコードには驚きました。

if (a =! b) { // let it be on false
    ...
}

ただし、aに値が割り当てられることはありません。この演算子は何についてですか?

175
m0nhawk

これは、1つの演算子ではなく、=!の2つの演算子です。難読化された書き方かもしれません

a = !b;
if (a) {
    // whatever
}

abの論理逆数に設定し、結果がtrueであるかどうかをテストします(または同等に、bがfalseであったかどうかをテストします)。

または、a != bのタイプミスである可能性があります。

391
Mike Seymour

昔、恐竜が地球を歩き回り、CがPDP-11上の第5版UNIXで実行されたとき、=!は「等しくない」演算子でした。この使用法はStandard Cの作成により廃止されたため、a = !bのように「論理逆数を割り当てる」ことを意味します。これは、コンパイラが何を考えているかをコードで読み取るhum​​ansを明確にするために、常にバイナリ演算子をスペースで囲むための適切な引数です。

誰もこれに言及していないことに少し驚いていますが、それでも私はその古いCコンパイラに触れたSOユーザーだけかもしれません。

279
Wexxor

aには、その行のbのブール否定が割り当てられます。それはただの誤ったフォーマットです

if( a = !b ) {

...そして条件内の邪悪な隠された割り当て。

54
Timbo
a =! b 

置くだけの面白い方法です

a = !b

つまり、not baへの割り当て。

式の値は、割り当て後のaです。

以下のコードを使用すると、式a = !bの値が!false(つまりtrue)であることがわかります。また、aの値(true)を確認することにより、割り当てが行われたことがわかります。

#include <iostream>

int main() 
{ 
    bool a = false;
    bool b = false;

    if(a)
        printf("a is true!\n");
    else
        printf("a is false!\n");

    if(a = !b)
        printf("expression is true!\n");
    else
        printf("expression is false!\n");

    if(a)
        printf("a is true!\n");
    else
        printf("a is false!\n");

}

結果:

a is false!
expression is true!
a is true!
46
splrs

C++の演算子

C/C++演算子リストによると、=!などの演算子はありません。ただし、演​​算子!=Not equal to比較演算子/関係演算子)があります

2つの可能性があります。

  1. それはcould=!演算子がifステートメントにあり、誰かが!=の代わりに=!を入力しようとしていることに気付いたので、タイプミスです!=trueまたはfalseを返す比較演算子であるためです。
  2. おそらく、開発者はbのブール否定をaに割り当てようとしましたが、タイプミスを犯し、等号の後にスペースを置くのを忘れていました。とにかく、これがコンパイラーによる解釈方法です。 c ++の演算子の優先順位
    • 演算子論理NOT(!)precedence3および結合性右から左
    • 演算子直接割り当て(=)優先順位16および結合性右から左
35
Simpal Kumar

これらは2つの異なる演算子です:=(割り当て)演算子と!演算子。基本的に、aの否定値bへの割り当てに変換できます。

if (a = !b)

しかし、おそらくユーザーが書くつもりだったのは、!=演算子でした。

if (a != b)
21
Shoe

これは単一の演算子ではありませんが、コードを難読化するのに最適な方法です。

代わりにa=!bと書かれている場合、空白が原因で単一の演算子であると信じられない可能性があります。

コンパイラーは、ステートメント全体を括弧のセットでラップしない限り、条件式での割り当てに関する警告があります。これは、この警告が役立つ場合の完璧な例です。

これらのステートメントは両方とも機能的に同一ですが、一方は警告を生成し、もう一方は生成しません:

if (a =! b)   // Generates a warning with `-Wparentheses` (gcc)

if ((a =! b)) // No such warning

-括弧

真理値が期待されるコンテキストに割り当てがある場合、または優先順位が混乱することが多い演算子がネストされている場合など、特定のコンテキストで括弧が省略されている場合に警告します。

もちろん、これはあなたが責任あるプログラマーであり、実際にコンパイラーが吐き出す警告を読むことを前提としています。


より合理的な方法で空白を使用すると、ステートメントは実際には次のようになります。

if (a = !b) // Assign A the value of (logical) NOT B and then test the truth

上記のコンパイラ警告は、このコードを書いた人が!=を誤って転置した場合に実際に役立ちます。ただし、元の質問の不可解なインラインコメントから、a = !bはおそらく著者の意図です。

20

C++には=!演算子がありません。つまり、これはすぐに=演算子の後に!演算子が続くことを意味します。したがって、if状態にa = !bがあるだけです。

18
AnT

これはすべて、コードの明快さに関するものです。

次のように記述する必要があります:if (a = !b)

if (a = !b)は、a!bに割り当てられている場合と同じです。したがって、技術的には、割り当て操作である=と論理式である!の2つの個別の演算子が使用されます。

=!の間にスペースを入れるだけで、この混乱を解決できます。

12
Ryman Holmes

これには3つの理由があります:

  1. !=演算子のタイプミスである可能性があり、等しくないことを意味します。 例:

    if (a != b) {
        // a is not equal to b
    }
    
  2. a == !bの入力ミスである可能性があります。つまり、abではなく、ブール値で最もよく使用されます。 例:

    if (a == !b) {
        // The boolean a is equal to not b (a is not equal to b)
    }
    
  3. aの逆にbを割り当てようとしている可能性があります。 例:

    bool a = !b; // Sets a to the opposite of b
    
11
Jojodmo

これは、執筆または印刷の間違いの1つだと思います。コンパイル時エラーが発生するため、このコードをコンパイルできない場合。そして、これはif句の中にあり、戻り値の型はブール型でなければなりません。それではどうすればそれが可能でしょうか。答えは単純な間違いか、マイクが言ったように難読化された書き方です

そして、変数aとbの両方がaは(not)bと等しい i.e(a =!b)としてコンパイルされるブール値である場合にのみ可能です。

10
Ranjit

a!bに割り当てられているため、これを取得できます。

6
Nitin Misra

私はあなたの質問に答えようとしています。そして、マイクの answer に同意して、合計します。

a=!!bでも理解できます。
コードa=!b0aに返し、a=!!b1aに返します。

=!は単一の演算子ではなく、これら2つを組み合わせたものです。これらのタイプの質問は、学生にコーディングスキルをチェックするを誤って導くように求められます。

4
Sudhir Yadav