Забавный вопрос встретил на одном форуме. Участник форума спрашивал, что означает оператор
!!, является ли он стандартным оператором языков С/С++, или это расширение конкретного компилятора.
Этот вопрос - пример того, что можно так заработаться, что когда встречается простая, но неиспользуемая никогда в собственной практике программиста конструкция, то программист может растеряться от неожиданности.
Естественно никакого нового оператора
!! в С/С++ не существует. Это конструкция представляет собой последовательное применение дважды стандартного оператора отрицания
!. Почему же вызывает удивление ее наличие в коде? Дело в том, что не сразу понятен смысл ее использования, то есть а зачем это делается? Ззачем два раза подряд применяется операция отрицания?
На самом деле этот прием распространен в языке С времен стандарта С89, где отсутсвует булевый тип. Иногда требуется для значений выражений, отличных от нуля, сопоставить значение равное 1. То есть имитируется с помощью числа целого типа булевый тип, принимающий только два значения: 0 и 1.
Допустим, мы ввели определение такого булева типа. Это можно сделать по разному. Либо с помощью
typedef , как, например,
typedef int bool_t; Либо с помощью перечисления:
typedef enum { false, true } bool_t; Однако возникает вопрос, а как сделать так, чтобы переменная нововведенного типа получала только значения равные 0 и 1?
То есть допутсим мы объявили
typedef int bool_t;
bool_t bFlag;
int x = 10;
И хотим переменной
bFlag присвоить значение либо 0, либо 1 в зависимости от того, отлично ли от нуля значение переменной
x. Как это проще сделать?
Можно было бы написать
bFlag = ( x ) ? 1 : 0;
Но это довольно вычурная конструкция. Проще же на самом деле написать
bFlag = !!x;
Дело в том, что соогласно стандарту С значением операции отрицания является точно одно из двух значений: либо 0, либо 1. Поэтому когда мы первый раз применили отрицание
! к
x, мы получили 0, а второе применение операции отрицания
! даст нам то, что нужно, то есть в данном конкретном случае 1.
Поэтому применение последовательно двух отрицаний
!! к выражению, позволяет получить либо 1, если выражение отлично от 0, либо 0, если выражение равно 0, то есть смоделировать область значений для булева типа.