Логические операторы в C

Мне трудно понять, как работают логические операторы в C. Я уже понимаю, как работают операторы битового уровня, и я также знаю, что логические операторы обрабатывают ненулевые аргументы как представляющие ИСТИНА, а нулевые аргументы как представляющие ЛОЖЬ.

Но скажем, у нас есть 0x65 && 0x55. Я не понимаю, почему и как эта операция дает 0x01.

Я пытался преобразовать его в двоичный файл, но я не могу понять, как это работает.


person FranXh    schedule 08.09.2012    source источник
comment
Поскольку 0x65 не равно 0, равно как и 0x55, && является логическим и: true и true истинно, поэтому ответ равен 1.   -  person Kwariz    schedule 08.09.2012


Ответы (8)


&& — это логическое AND (в отличие от &, которое является побитовым AND). Он заботится только о том, чтобы его операнды были нулевыми/ненулевыми значениями. Нули считаются false, а ненулевые — true.

В вашем случае оба операнда не равны нулю, поэтому они обрабатываются как true, что также приводит к результату true. C представляет true как 1, объясняя общий результат вашей операции.

Если вы измените операцию на &, вы получите побитовую операцию. 0x65 & 0x55 даст вам результат 0x45.

person Sergey Kalinichenko    schedule 08.09.2012

&& оператор:

Если левый операнд и правый операнд оба отличаются от 0, он оценивается как 1, в противном случае он оценивается как 0.

Если левый операнд равен 0, правый операнд не оценивается и результатом является 0.

0x65 && 0x55 оценивается как 1.

person ouah    schedule 08.09.2012
comment
@AaronMcDaid (C99, 6.5.13p3) Оператор && должен давать 1, если оба его операнда не равны 0; в противном случае возвращается 0. - person ouah; 08.09.2012
comment
Ага! Тогда я удалю свой ответ! - person Aaron McDaid; 08.09.2012

&& — это логический оператор, а не побитовый. И 0x65, и 0x55 верны, поэтому результатом является истинное число. 0x01 - настоящее число.

Двоичные представления вступают в игру только для побитовых операций. Выражение 0x65 & 0x55 равно 0x45.

person aschepler    schedule 08.09.2012

Любое выражение, которое оценивается как 0, является ложным. И любое выражение, отличное от нуля, истинно. Так что и 0x65, и 0x55 верны.

0x65 && 0x55

=> правда && правда => правда

person kjohri    schedule 08.09.2012

Я попытался преобразовать его в двоичный

Это могло помешать пониманию. Точные битовые шаблоны 0x65 и 0x55 совершенно не имеют отношения к требуемому результату, важно только то, что они оба отличны от нуля. Вы можете рассматривать a = (0x65 && 0x55) как эквивалент чего-то вроде:

if (0x65 != 0) goto condition_false;
if (0x55 != 0) goto condition_false;
a = 1;
goto condition_end;
condition_false:
a = 0;
condition_end:

Данная реализация может генерировать код более эффективно, чем это (хотя я видел довольно много такого кода, где каждый if ... goto был тестом и ветвью в сборке). Более эффективный код может включать некоторые битовые операции, чтобы избежать ветвлений. Если на то пошло, в этом примере с константами компилятор, вероятно, просто выдаст a = 1;.

Однако значение оператора && связано с условным выполнением. Например, если вы пишете f() && g(), то гарантируется, что когда f возвращает ложное значение, g не вызывается. Если можно получить тот же результат путем перестановки битов, то это, скорее всего, бонус к производительности.

person Steve Jessop    schedule 08.09.2012

C и C++ имеют три логические операторы: логическое не(!), логическое И(&&) и логическое ИЛИ(||). Для логических операторов 0 является ложным, а все, что не равно нулю, является истинным. В этой таблице истинности показано, как работает каждый логический оператор (будет использоваться 1 вместо true):

p     q     p && q    p || q
=     =     ======    ======
1     1       1         1
1     0       0         1
0     1       0         1
0     0       0         0

Таблица истинности для ! выглядит следующим образом:

p    !p
=    ===
1     0
0     1

Для вашего конкретного случая:

0x65 && 0x55

Поскольку оба операнда 0x65 и 0x55 оцениваются как true, все выражение оценивается как true и, таким образом, расширяется до 1, что относится к c99, но другие ответы в связанной ветке объясняют, как это применимо и до c99.

person Shafik Yaghmour    schedule 20.05.2013

C определяет значения больше нуля как «Истина». Поскольку и 0x65, и 0x55 соответствуют этому условию, результатом также является True, что на выходе равно 1, или, в шестнадцатеричном представлении, 0x01.

Альтернативным стилем написания вашего кода может быть:

return (0x65 верно) и (0x55 верно);

person irrenhaus3    schedule 08.09.2012

Как вы сказали, логические операторы рассматривают ненулевые аргументы как представление

 (0x65 && 0x55) is equal as (0x65 > 0) && (0x55 > 0)

 0x65 > 0 get true and 0x55 > 0 get true as well

 So (0x65 && 0x55)  is equal true && true = 1
person wbao    schedule 08.09.2012