Что такое"!!"в C? [дубликат]


На этот вопрос уже есть ответ здесь:

Я столкнулся со следующим фрагментом:

pt->aa[!!(ts->flags & MASK)] = -val;
  1. Что означает !! (двойные восклицательные знаки / восклицательные знаки/ два оператора не) в c?
  2. разве это не (!!NULL) == NULL?
7 37

7 ответов:

! это отрицание. Так что !! есть отрицание отрицания. Важно то, что результатом будет int.

  • !!x если x == 0 есть !!0, то есть !1, то есть 0.
  • !!x Если x != 0 есть !!(!0), то есть !!1, то есть !0, то есть 1.

!! обычно используется, если вы хотите преобразовать любое ненулевое значение в 1, будучи уверенным, что 0 остается 0.

И действительно, !!NULL == NULL, так как !!NULL == !!0 и !!0 == !1 и, наконец, !1 == 0.

Следовательно, в приведенном вами коротком фрагменте кода подстрочный индекс массива будет либо 0, если значение выражения в скобках равно NULL, либо 1 в противном случае.

Обычно (ab) используется для преобразования любого значения в ints 0 или 1 путем повторного применения булевого оператора not, !.

Например: !56 равно 0, так как 56 является "истинным", если рассматривать его как булево. Это означает, что !!56 равно 1, так как !0 равно 1.

!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;

Сгенерированный код будет, безусловно, идентичен.

Преобразует число в каноническое булево.

И обратите внимание, что в этом случае это очень важно, так как результат используется для индексирования массива.

  1. !!x - это просто !(!x).
  2. если NULL определено как 0, то !!NULL == !!0 == !(!0) == !(1) == 0.

!! это хороший способ успокоить компилятор в определенных ситуациях, таких как присваивание в условном выражении с более чем одним выражением, например:

int _blah = 100;
int *blah;
if ( _blah > 100 && !!(blah = &_blah) ) {
// do stuff
}

Я не рекомендую этого - предупреждения обычно существуют для обеспечения надлежащей практики кодирования.