&& и || не логические, а условные операторы?

62

Меня немного смущает документация MSDN C #, в которой говорится, что &и |являются логическими операторами, &&а ||также условными операторами.

Я продолжаю звонить &&, ||и !логические операторы, так что я не прав?

Джон V
источник
4
Это кажется нелогичным, но между этими двумя классами есть важное различие, и очень важно, чтобы вы не предполагали, что, скажем, |взаимозаменяемы ||, даже если во многих случаях они могут быть взаимозаменяемы без видимых изменений в поведении программы.
Даниэль Р Хикс

Ответы:

120

Меня немного смущает документация MSDN C #, в которой говорится, что &и |являются логическими операторами, &&а ||также условными операторами. Я продолжаю звонить &&, ||и !логические операторы, так что я не прав?

Нет; ты прав.

В документации MSDN есть множество мелких, в основном незначительных ошибок номенклатуры; Я пытался вытащить как можно больше из них, но в тех случаях, когда это не является вопиюще неправильным и вводящим в заблуждение, это не всегда разумное использование времени. Перейдите к спецификации, если вы хотите определенное утверждение о названии функции C #.

Итак: соответствующим полномочием является спецификация C #, которая гласит в разделе 7.11:

&, ^И |операторы называются логические операторы.

Затем происходит дальнейшее разбиение встроенных логических операторов на целочисленные, перечислимые, логические и логические операторы с нулевым логическим значением. Есть также определенные пользователем логические операторы; смотрите спецификацию для деталей.

В разделе 7.12 мы имеем

Эти &&и ||операторы называются условные логические операторы. Их также называют «короткозамкнутыми» логическими операторами.

Так что все они являются логическими операторами. Некоторые из них являются условными логическими операторами .

Что делает условные логические операторы условными ? Можно предположить, что это потому, что они обычно используются в условных выражениях ( if) или условных выражениях ( ? :). Настоящая причина указана в спецификации:

&&И ||операторы являются условными версиями &и |операторы: операция x && yсоответствует операциям x & y, за исключением того, что yоценивается только если xне является ложным. Операция x || yсоответствует операции x | y, за исключением того, что yона оценивается, только если xона не соответствует действительности.

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

Мы можем увидеть это более наглядно, заметив, что условные логические операторы являются просто «синтаксическими сахарами» для условных выражений . x && yэто просто более приятный способ написания x ? y : falseи x || yпросто более приятный способ написания x ? true : y. Условные логические выражения на самом деле являются условными выражениями.

Существует также пользовательская форма условного логического оператора, и она немного сложнее. Подробности смотрите в спецификации.

Дальнейшее чтение, если эта тема вас интересует:

Эрик Липперт
источник
3
@RobertHarvey: Да, тот факт, что & может работать с bools, целочисленными типами или типами enum, но && работает только с bools, не имеет никакого отношения к выбору именования одного из них как «условной» формы оператора. Условный оператор является условным, потому что он имеет условную ветвь в своей семантике вычисления.
Эрик Липперт
16
У меня сложилось впечатление, что термин «оператор короткого замыкания» гораздо более популярен (и, вероятно, менее неоднозначен), чем «условный оператор» в описанном смысле.
Док Браун
15
@DocBrown: это, безусловно, популярно, но я всегда находил это имя вводящим в заблуждение; кажется, что он был придуман кем-то, кто считал, что «короткое замыкание» и «короткое замыкание» для получения результата - это одно и то же. Короткое замыкание - опасная неисправность, которая может быстро разрушить электрическую систему. Мы назвали «небезопасные» блоки в C # «небезопасными», потому что они опасны, если используются неправильно ; давайте не будем называть их приятными, но вводящими в заблуждение ценными именами. Даже не заводите меня на оператора Элвиса. :-)
Эрик Липперт
26
@EricLippert: Хотя «короткое замыкание» может показаться страшным для широкой публики, я не думаю, что K & R были озадачены фактическим определением. В электротехнике замыкание цепи не всегда является опасной неисправностью, фактически мы делаем это намеренно все время. Это просто означает отключить нежелательную часть цепи, дав электричеству более короткий путь.
hackerb9
1
@CortAmmon: вы захотите прочитать следующий абзац, где я призываю семантику определяемого пользователем оператора немного отличаться и что вы должны увидеть спецификацию для деталей.
Эрик Липперт
27

В C # это все логические операторы.

int x = 0xABCD & 0xFF // x == 0xCD

&&и ||называются « условными логическими операторами», потому что они являются короткими замыканиями.

bool someOtherCondition = true;
if (x == 0xEF && someOtherCondition) // someOtherCondition is not evaluated, 
                                     // because x == 0xEF is false

Обратите внимание, что эта терминология отличается от языка к языку. В C и C ++ &&и ||есть просто логические операторы. В Java &и |называются побитовые операторы , а C и C ++ классифицируют их как арифметические операторы .

Роберт Харви
источник
3
Да, Microsoft является авторитетом, но авторитетным документом является спецификация. Смотрите раздел 7.12, Условные логические операторы .
Эрик Липперт
8
Мораль этой истории такова: важнее точно понять, что делают эти операторы, чем быть точным в отношении их имен.
Роберт Харви
21
Сосредоточьтесь на том, что делают операторы, и перестаньте зацикливаться на словарном запасе. Смотрите также Наименование считается вредным .
Роберт Харви
4
+1. Все, что перечислено в вопросе, это просто операторы, которые принимают одно или два выражения и оценивают их как значения. Прилагательные - ненужное разделение волос.
Blrfl
-2

Дело в том, что &и |являются побитовыми операторами, то есть они применяются к битовым строковым значениям и дают их. И побитовый это очень используемый термин среди программистов.

Например 0xff & 0x00 == 0x00, пока 0xff | 0x00 == 0xff.

И &&и ||применяются к условиям, и дают обычные значения условий; т.е. trueи false.

Например true && false == false, пока true || false == true.

Поэтому &&и ||можно было бы назвать условные операторы, хотя это не обычный термин среди программистов.

Конечно, каждый программист на C, C ++, Java и C # знает все это. Но я думаю, что это неправильно понято, потому что «условный оператор» не является термином, часто используемым нами, программистами.

Хилтон Фернандес
источник
5
Конечно, каждый программист на C, C ++, Java и C # знает все это. Это очень грубо писать, подразумевая, что ОП глупо. То же самое, написав нам, программистам , вы исключаете ОП. Пожалуйста, не делай этого.
DarkDust
1
Я не думаю, что ваш более поздний ответ приносит какую-либо дополнительную ценность после принятого ответа Эрика Липперта, и, кроме того, он неверен в том смысле, что он не понимает сути вопроса.
Хонза Зидек
@DarkDust Каждый программист на C, C ++, Java и C # должен понимать эти операторы. Это не грубость, а факт .
Phil1970
1
@ Phil1970: OP, кажется, понимает этих операторов, речь идет об уточнении имен . В этом свете, подчеркнув соответствующие термины в ответе Хилтона, его предложение можно интерпретировать как означающее, что каждый программист знает об этих деталях именования, но вы этого не делаете . Это является неправильным (как можно видеть в обсуждении других ответов) и его фразировка груба.
DarkDust
4
Дорогие все, извините, если мой ответ выглядел грубым. Английский не 1-й язык. В любом случае, я никогда не собирался подразумевать, что ОП не был программистом. Напротив, я имел в виду, что он или она были смущены необычным наименованием в тексте, который он или она читал. Все, что я пытался сделать, это выяснить необычное именование фрагментами программы.
Хилтон Фернандес