次のスニペットに遭遇しました。
pt->aa[!!(ts->flags & MASK)] = -val;
!!
(二重感嘆符/感嘆符/ 2つのNOT演算子)はcで何を表しますか?- そうじゃない
(!!NULL) == NULL
?
次のスニペットに遭遇しました。
pt->aa[!!(ts->flags & MASK)] = -val;
!!
(二重感嘆符/感嘆符/ 2つのNOT演算子)はcで何を表しますか?(!!NULL) == NULL
?!
否定です。!!
否定の否定もそうです。重要なのは、結果がになるという事実ですint
。
!!x
の場合、つまりx == 0
、つまり。!!0
!1
0
!!x
の場合、つまりx != 0
、つまり、つまり。!!(!0)
!!1
!0
1
!!
0が0のままであることを確認しながら、ゼロ以外の値を1に変換する場合に一般的に使用されます。
そして確かに!!NULL == NULL
、以来!!NULL == !!0
、!!0 == !1
そして最後に!1 == 0
。
したがって、短いコードで引用した配列の添え字は0
、括弧内の式の値がの場合、またはそうでない場合のいずれかNULL
になり1
ます。
int
ブール否定演算子を繰り返し適用することにより、任意の値をs 0または1に変換するために一般的に(ab)使用されます!
。
たとえば!56
、ブール値として表示した場合、56は「真」であるため、は0です。これは、!!56
が1であるため、が1であることを意味し!0
ます。
!E
と同じE == 0
です。!!E
と同じ(E == 0) == 0
です。!!
ブール値を正規化するために使用されます。
C99では、次のように置き換えることができます
#include <stdbool.h>
pt->aa[(bool)(ts->flags & MASK)] = -val;
もちろん、コードをC89に移植できるようにする場合は、実行したほうがよいでしょう。トリックまたは
pt->aa[(ts->flags & MASK)!=0] = -val;
また
pt->aa[(ts->flags & MASK)?1:0] = -val;
生成されたコードは確かに同一です。
数値を正規のブール値に変換します。
また、この場合、結果は配列のインデックス付けに使用されるため、これを行うことが重要であることに注意してください。
!!x
はただの!(!x)
です。NULL
が0として定義されている場合、 !!NULL == !!0 == !(!0) == !(1) == 0
。!! は、複数の式を使用した条件付きでの割り当てなど、特定の状況でコンパイラを静めるための適切な方法です。例:
int _blah = 100;
int *blah;
if ( _blah > 100 && !!(blah = &_blah) ) {
// do stuff
}
私はこれをお勧めしません-警告は通常、適切なコーディング慣行を強制するためにあります。