Я просто задавался вопросом, существует ли логический оператор XOR в C (что-то как && для И но для XOR). Я знаю, что могу разделить XOR на ANDs, NOTs и ORs, но простой XOR был бы намного лучше. Затем мне пришло в голову, что, если я использую нормальный побитовый оператор XOR между двумя условиями, он мог бы просто работать. И для моих тестов это сделало.
Рассмотрите:
int i = 3;
int j = 7;
int k = 8;
Только ради этого довольно глупого примера, если бы мне нужен k, чтобы быть или больше, чем я или больше, чем j, но не оба, XOR был бы довольно удобен.
if ((k > i) XOR (k > j))
printf("Valid");
else
printf("Invalid");
или
printf("%s",((k > i) XOR (k > j)) ? "Valid" : "Invalid");
Я поместил поразрядный XOR ^, и он произвел "Недопустимый". Помещение результатов этих двух сравнений в двух целых числах привело к этим 2 целым числам для содержания 1, следовательно XOR произвел ложь. Я затем попробовал его и и | побитовые операторы, и оба дали ожидаемые результаты. Все это имеет смысл, зная, что истинные условия имеют не нулевое значение, пока ложные условия имеют нулевые значения.
Я задавался вопросом, там причина использовать логический && и ||, когда побитовые операторы и, | и ^ работают все равно?
Вам не нужен логический 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
Я поищу в избранном, и вставлю сюда ссылку позже....
В C аргументы логических операторов обрабатываются как логические значения - все, что ноль считается "ложным", а все остальное (да, отрицательные значения тоже) считаются "правда". Побитовые операции работают с отдельными битами и, как уже отмечал Нил, не подвержены оценке короткого замыкания, как логические операции.
В вашем примере результаты полностью действительны и ожидаемы, поскольку побитовое xor
между двумя единицами равно нулю.
Побитовые операторы не работают "точно так же", как операторы && и ||. Для начала, && и || выполняют короткозамкнутую оценку, в то время как битовые операторы этого не делают. Другими словами, вы не можете сделать что-то вроде этого с побитовыми операторами:
int * p = 0;
(p != 0) && (*p = 1);
потому что если бы вы сказали:
(p != 0) & (*p = 1);
оба подвыражения были бы оценены, и вы бы разыменовали нулевой указатель.
Побитовый XOR не работает, как логический XOR, когда его операндами являются целые значения:
2^4 ? "Valid" : "Invalid"
дает "Valid", но должен давать "Invalid"
Если вам нужен логический оператор xor в C, то вы можете использовать этот:
#define xor != 0 ^ !!
Он работает путем преобразования обеих сторон выражения в булевы и их ксоринга. Вы можете использовать его как && или ||, например, так:
if (a xor b)
AFAICT, с ним нет никаких проблем.