Вопрос

& имеет &&. | имеет ||.Почему не ^ иметь ^^?

Я понимаю, что это не будет коротким замыканием, но у него будет другая семантика.В С, true на самом деле является любым ненулевым значением.Побитовое исключающее ИЛИ не всегда совпадает с логическим исключающим ИЛИ:

int a=strcmp(str1,str2);// evaluates to 1, which is "true"
int b=strcmp(str1,str3);// evaluates to 2, which is also "true"
int c=a ^^ b; // this would be false, since true ^ true = false
int d=a ^ b; //oops, this is true again, it is 3 (^ is bitwise)

Поскольку вы не всегда можете полагаться на истинное значение 1 или -1, не было бы ^^ оператор будет очень полезен?Мне часто приходится делать странные вещи вроде этого:

if(!!a ^ !!b) // looks strange
Это было полезно?

Решение

Деннис Ритчи отвечает

  

Существуют как исторические, так и практические причины, по которым нет оператора ^^ .      

Практика такова: для оператора нет особой пользы. Суть & amp; и || заключается в том, чтобы использовать их оценку короткого замыкания не только из соображений эффективности, но чаще для выразительности и правильности. < ш>   [...]
  В отличие от этого, оператор ^^ всегда вынуждает вычислять обе ветви выражения, поэтому повышение эффективности отсутствует. Кроме того, ситуации, в которых действительно требуется ^^ , довольно редки, хотя примеры могут быть созданы. Эти ситуации становятся все более редкими и странными, когда вы складываете оператор--

if (cond1() ^^ cond2() ^^ cond3() ^^ ...) ...
     

выполняет последующее точно, когда нечетное число из condx () истинно. Напротив, аналоги & amp; и || остаются достаточно правдоподобными и полезными.

Другие советы

Технически, один уже существует:

a != b

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

Edit:

Комментарий Volte :

(!a) != (!b)

правильно, потому что мой ответ выше не работает для типов int . Я удалю мой, если он добавит свой ответ.

Снова отредактируйте:

Может быть, я что-то забываю в C ++, но чем больше я об этом думаю, тем больше я удивляюсь, почему вы вообще пишете if (1 ^ 2) . Цель для ^ состоит в том, чтобы исключить или два числа вместе (что означает другое число), а не преобразовывать их в логические значения и сравнивать их значения истинности.

Кажется, что это было бы странным предположением для дизайнера языка.

Для не-bool операнды, я думаю, вам бы хотелось, чтобы a ^^ b оцениваться как:

(a != 0) ^ (b != 0)

Что ж, у вас есть вариант выше, и у вас есть несколько вариантов, перечисленных в других ответах.

Оператор ^^ было бы излишним для bool операнды.Говоря только о логических операндах, давайте в целях рассуждения представим, что ^ было только побитовым, и это ^^ существовал как логический XOR.Затем у вас есть следующие варианты:

  • & - Побитовое И - всегда оценивается оба операнда.
  • && - Логическое И - не всегда оцениваются оба операнда.
  • | - Побитовое ИЛИ - всегда оценивается оба операнда.
  • || - Логическое ИЛИ – не всегда оцениваются оба операнда.
  • ^ - Побитовое исключающее ИЛИ - всегда должны оцениваться оба операнда.
  • ^^ - Логическое исключающее ИЛИ – всегда должно оцениваться оба операнда.

Почему они не создали ^^ по существу преобразовать числовые значения в bools, а затем действовать как ^?Это хороший вопрос.Возможно, потому, что это потенциально более запутанно, чем && и ||, возможно, потому, что вы можете легко построить эквивалент ^^ с другими операторами.

Я не могу сказать, что было в головах Кернигана и Ричи, когда они изобрели C, но вы кратко упомянули, что «не будет короткого замыкания», и я предполагаю, что причина: не возможно реализовать это последовательно. Вы не можете замкнуть XOR, как вы можете И и ИЛИ, поэтому ^^ не может быть полностью параллельным & amp; & amp; и || Таким образом, авторы вполне могли бы решить, что создание операции, которая своего рода похожа на параллель с другими, но не совсем, было бы хуже, чем ее отсутствие вообще.

Лично я по главной причине использую & amp; & amp; и || для короткого замыкания, а не для битового. На самом деле я очень редко использую побитовые операторы вообще.

Еще один обходной путь для тех, которые опубликованы выше (даже если для этого требуется другая ветвь в коде):

if ( (a? !b : b ) )

это эквивалентно xor.

В Java оператор ^ действительно выполняет логическое XOR, когда используется с двумя логическими операндами (точно так же, как в & amp; и | в Java не короткое замыкание логического И и ИЛИ, соответственно, применительно к логическим значениям). Основное отличие от C / C ++ состоит в том, что C / C ++ позволяет смешивать целые и логические значения, а Java - нет.

Но я думаю, что это плохая практика - использовать целые числа как булевы. Если вы хотите выполнять логические операции, вам следует придерживаться либо значений bool , либо целых чисел, равных 0 или 1. Тогда ^ отлично работает как логический XOR.

Аналогичным вопросом было бы спросить, как бы вы сделали не замыкающие накоротко логические AND и OR в C / C ++? Обычный ответ - использовать операторы & amp; и | соответственно. Но опять же, это зависит от того, являются ли значения bool или 0 или 1. Если вы разрешите какие-либо целочисленные значения, то это тоже не сработает.

Независимо от случая за или против ^^ в качестве оператора, ваш пример с strcmp () отстой. Он не возвращает значение истины (истина или ложь), он возвращает отношение между своими входами, закодированное как целое число.

Конечно, любое целое число может интерпретироваться как значение истинности в C, и в этом случае 0 равно "false" и все другие значения являются «истинными», но это противоположно тому, что возвращает strcmp () .

Ваш пример должен начаться:

int a = strcmp(str1, str2) == 0; // evaluates to 0, which is "false"
int b = strcmp(str1, str3) == 0; // evaluates to 0, which is also "false"

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top