В чем смысл логических операторов в C? - PullRequest
5 голосов
/ 05 мая 2010

Мне просто интересно, есть ли в C логический оператор XOR (что-то вроде && для AND, но для XOR). Я знаю, что могу разделить XOR на AND, NOT и OR, но простой XOR был бы намного лучше. Затем мне пришло в голову, что если я использую обычный битовый оператор XOR между двумя условиями, это может просто сработать. И для моих тестов это сделал.

Рассмотрим:

int i = 3;
int j = 7;
int k = 8;

Просто ради этого довольно глупого примера, если мне нужно, чтобы k было либо больше i , либо больше j , но не оба, XOR было бы очень удобно.

if ((k > i) XOR (k > j))
   printf("Valid");
else
   printf("Invalid");

или

printf("%s",((k > i) XOR (k > j)) ? "Valid" : "Invalid");

Я поставил битовый XOR ^ , и он выдал "Invalid". Помещение результатов двух сравнений в два целых числа привело к тому, что 2 целых числа содержали 1, следовательно, XOR выдает false. Затем я попробовал это с & и | побитовые операторы и оба дали ожидаемые результаты. Все это имеет смысл, зная, что истинные условия имеют ненулевое значение, тогда как ложные условия имеют нулевые значения.

Мне было интересно, есть ли причина использовать логические && и || когда побитовые операторы &, | и ^ работать точно так же?

Ответы [ 5 ]

13 голосов
/ 05 мая 2010

Вам не нужен логический XOR, я забыл вопрос SO, но он похож на то, что вы думаете, в основном нам не нужен XOR, он эквивалентен ! = в любом случае

FALSE XOR FALSE == FALSE
FALSE XOR TRUE == TRUE
TRUE XOR FALSE == TRUE
TRUE XOR TRUE == FALSE


FALSE != FALSE == FALSE
FALSE != TRUE == TRUE
TRUE != FALSE == TRUE
TRUE != TRUE == FALSE

Я буду искать в избранном и вставлю сюда ссылку позже ...

11 голосов
/ 05 мая 2010

Битовые операторы не работают "точно так же", как && и || оператор. Для начала, && и || выполнять короткозамкнутую оценку, тогда как побитовые операторы - нет. Другими словами, вы не можете делать что-то подобное с побитовыми операторами:

int * p = 0;
(p != 0) && (*p = 1);

потому что, если вы сказали:

(p != 0) & (*p = 1);

оба подвыражения будут оценены, и вы разыменуете нулевой указатель.

1 голос
/ 30 мая 2010

Если вам нужен логический оператор xor в C, то вы можете использовать это:

#define xor != 0 ^ !!

Работает путем преобразования обеих сторон выражения в логические значения и их ксоринга. Вы можете использовать его так же, как если бы вы использовали && или ||, например:

if (a xor b)

AFAICT, с этим проблем нет.

1 голос
/ 05 мая 2010

В C аргументы логических операторов обрабатываются как логические значения - все ноль рассматривается как «ложь», а все остальное (да, и отрицательные значения тоже) являются «истиной». Битовые операции работают с отдельными битами, и, как уже отмечал Нейл, не подвержены оценке короткого замыкания, как и логические операции.

В вашем примере результаты полностью верны и ожидаемы, так как побитовое значение xor между двумя равно нулю.

1 голос
/ 05 мая 2010

Побитовое XOR не работает как логический XOR, когда его операндами являются целые значения:

2^4 ? "Valid" : "Invalid"

дает "Действительный", но должен давать "Неверный"

...