Допустим, у меня есть логическое условие, a AND b OR c AND d
и я использую язык, в котором AND
прецедент операции выше, чем OR
. Я мог бы написать эту строку кода:
If (a AND b) OR (c AND d) Then ...
Но на самом деле это эквивалентно:
If a AND b OR c AND d Then ...
Есть ли аргументы за или против включения лишних скобок? Практический опыт подсказывает, что стоит включить их для удобства чтения? Или это признак того, что разработчик должен действительно сесть и стать уверенным в основах своего языка?
coding-style
operator-precedence
Джефф Бриджман
источник
источник
2 * 3 + 2
может быть так же, как,(2 * 3) + 2
но второй легче читать.Ответы:
Хорошие разработчики стремятся написать понятный и правильный код . Скобки в условных выражениях, даже если они не являются строго обязательными, помогают в обоих случаях.
Что касается ясности , думайте о скобках как о комментариях в коде: они не являются строго необходимыми, и теоретически компетентный разработчик должен иметь возможность вычислять код без них. И все же эти подсказки чрезвычайно полезны, потому что:
Кроме того, дополнительные скобки, такие как отступы, пробелы и другие стандарты стиля, помогают визуально организовать код логическим способом.
Что касается правильности , то условия без скобок - это рецепт для глупых ошибок. Когда они случаются, они могут быть ошибками, которые трудно найти - потому что часто неправильное условие будет вести себя правильно большую часть времени, и только изредка терпит неудачу.
И даже если вы поймете это правильно, следующий человек, который будет работать над вашим кодом, может и не добавлять ошибки в выражение или неправильно понимать вашу логику и, следовательно, добавлять ошибки в другом месте (как справедливо указывает LarsH).
Я всегда использую скобки для выражений, которые объединяются
and
иor
(а также для арифметических операций с аналогичными проблемами приоритета).источник
Не имеет значения, уверены ли вы в своем понимании языка. Что более важно, так это понимание языка n00b, который следует за вами.
Напишите свой код наиболее понятным и понятным способом. Дополнительные скобки часто (но не всегда) помогают. Помещение одной строки в строку часто помогает. Часто помогает последовательность в стиле кодирования.
Существует такая вещь, как слишком много скобок, но это одна из тех ситуаций, когда вам не понадобится совет - вы узнаете его, когда увидите. На этом этапе реорганизуйте свой код, чтобы уменьшить сложность оператора, а не убрать круглые скобки.
источник
There is such a thing as too many parenthesis
- ты явно не шучу;)да
Вы должны всегда использовать круглые скобки ... вы не контролируете порядок приоритета ... разработчик компилятора делает. Вот история, которая произошла со мной о неиспользовании скобок. Это затронуло сотни людей в течение двух недель.
Реальная причина мира
Я унаследовал приложение основного кадра. Однажды, из чистого синего это перестало работать. Вот и все ... Боже, он просто остановился.
Моя работа состояла в том, чтобы заставить его работать как можно быстрее. Исходный код не изменялся в течение двух лет, но внезапно он просто прекратился. Я попытался скомпилировать код, и он разбился на строке XX. Я посмотрел на строку XX, и я не мог сказать, что заставит линию XX разорваться. Я попросил подробные спецификации для этого приложения, и не было ни одного. Линия XX не была виновником.
Я распечатал код и начал просматривать его сверху вниз. Я начал создавать блок-схему того, что происходило. Код был настолько запутанным, что я едва мог понять его. Я бросил пытаться построить блок-схему. Я боялся вносить изменения, не зная, как это изменение повлияет на остальную часть процесса, тем более что у меня не было подробностей о том, что приложение делало или где оно находилось в цепочке зависимостей.
Итак, я решил начать с верхней части исходного кода и добавить whitespce и линейные тормоза, чтобы сделать код более читабельным. Я заметил, что в некоторых случаях были условия, которые объединялись,
AND
иOR
не было четкого различия между тем, какие данныеAND
редактировались и какие данныеOR
редактировались. Поэтому я начал ставить круглые скобки вокруг условийAND
иOR
условий, чтобы сделать их более читабельными.Когда я медленно спускался, убирая это, я периодически сохранял свою работу. Однажды я попытался скомпилировать код, и случилось нечто странное. Ошибка перепрыгнула через исходную строку кода и теперь была еще ниже. Поэтому я продолжал, speparating
AND
иOR
условие с круглыми скобками. Когда я закончил убирать это, это сработало. Пойди пойдиЗатем я решил посетить операционную мастерскую и спросить их, устанавливали ли они недавно какие-либо новые компоненты на основной раме. Они сказали да, мы недавно обновили компилятор. Хммм.
Оказывается, старый компилятор вычислял выражение слева направо независимо. Новая версия компилятора также оценивала выражения слева направо, но неоднозначный код, что означало неясное сочетание
AND
иOR
не могло быть разрешено.Урок, который я извлек из этого ... ВСЕГДА, ВСЕГДА, ВСЕГДА используйте парены для разделения
AND
условий иOR
условий, когда они используются в сочетании друг с другом.Упрощенный пример
IF Product = 191 OR Product = 193 AND Model = "ABC" OR Product = 201 OR Product = 202 AND Model = "DEF" ...
(код завален несколькими из них)Это упрощенная версия того, с чем я столкнулся. Были еще условия с составными логическими утверждениями.
Я помню, как это повлияло на:
IF ((Product = 191 OR Product = 193) AND Model = "ABC") OR ((Product = 201 OR Product = 202) AND Model = "DEF") ...
Я не мог переписать его, потому что не было никаких спецификаций. Первоначальный автор давно ушел. Я помню сильное давление. Весь грузовой корабль оказался в порту и не мог быть выгружен, потому что эта маленькая программа не работала. Нет предупреждения Без изменений в исходном коде. Меня осенило только спросить Сетевые Операции, изменили ли они что-нибудь, после того, как я заметил, что добавление паренсов сместило ошибки
источник
Да, если есть смешанные «и» и «или».
Также хорошая идея для (), что логически одна проверка.
Хотя лучше всего использовать хорошо известные функции предикатов и исключать большинство проверок и условий, оставляя их простыми и удобочитаемыми.
источник
a AND b
вероятно, следует заменить либо функцией, либо предварительно рассчитанным значением boolen, которое имеет более описательное имя.Скобки семантически избыточны, так что компилятору все равно, но это красная сельдь - реальная проблема - читаемость и понимание программистом.
Я собираюсь занять здесь радикальную позицию и дать сердечное «нет» скобкам
a AND b OR c AND d
. Каждый программист должен наизусть знать, что приоритет в булевых выражениях идет НЕ> И> ИЛИ , точно так же, как вспоминать « Пожалуйста, простите мою дорогую тетю Салли за алгебраические выражения» Избыточная пунктуация просто добавляет визуальный беспорядок в коде большую часть времени без пользы для читаемости программиста.Кроме того, если вы всегда используете круглые скобки в логических и алгебраических выражениях, то вы отказываетесь от возможности использовать их в качестве маркера для «чего-то хитрого, что происходит здесь - берегитесь!» То есть в тех случаях, когда вы хотите переопределить приоритет по умолчанию и вычислить сложение перед умножением или OR перед AND, круглые скобки - это приятный красный флаг для следующего программиста. Слишком много пользы от них, когда они не нужны, и ты становишься Мальчиком, который плакал.
Я бы сделал исключение для чего-либо за пределами области алгебры (булево или нет), такого как выражения указателя в C, где что-либо более сложное, чем стандартные идиомы, такие как
*p++
или,p = p->next
вероятно, должно быть заключено в скобки, чтобы сохранить разыменование и арифметику прямыми. И, конечно, все это не относится к языкам, таким как Lisp, Forth или Smalltalk, которые используют некоторую форму польской нотации для выражений; но для большинства основных языков логический и арифметический приоритет полностью стандартизирован.источник
AND
противOR
является довольно простой случай , который я хочу , чтобы другие разработчики на моей команде , чтобы знать. Я беспокоюсь о том, что иногда «использование скобок для ясности» на самом деле означает «использование скобок, поэтому мне никогда не нужно беспокоиться, чтобы узнать приоритет»..member
прежде унарные операторы, унарные перед тем бинарные операторы,*
и/
до того,+
и-
до того,<
и>
и==
прежде , чем&&
до того,||
прежде чем назначение. Эти правила легко запомнить, потому что они соответствуют моему «здравому смыслу» о том, как обычно используются операторы (например, вы не дадите==
больший приоритет, чем+
или1 + 1 == 2
перестаете работать), и они охватывают 95% вопросов, которые у меня возникнут ,Как я вижу это:
ДА Плюсы:
ДА Минусы:
НЕТ Плюсы:
НЕТ Минусов:
источник
3 * a^2 + 2 * b^2
легче читать, чем(3 * (a^2)) + (2 * (b^2))
, потому что формат и приоритет знакомы и стандартны. Точно так же вы можете (быть крайне) запретить использование функций и макросов (или компиляторов!), Чтобы сделать семантику вашего кода более явной. Очевидно, я не защищаю это, но я надеюсь ответить на ваш вопрос о том, почему должны быть ограничения (баланс) для того, чтобы сделать вещи явными.Если бы никому больше не пришлось снова просматривать мой код, я не думаю, что мне было бы все равно.
Но из моего опыта:
Я почти всегда так делаю, потому что доверяю своей способности быстро читать и не совершать небольших ошибок с паренами больше, чем ничего другого.
В вашем случае я бы почти наверняка сделал что-то вроде:
Да, это больше кода. Да, вместо этого я могу использовать модных операторов bool. Нет, мне не нравится, когда в будущем я буду читать код более 1 года, я неправильно понимаю причудливых операторов bool. Что если бы я писал код на языке, который имел другой приоритет И / ИЛИ и должен был вернуться назад, чтобы это исправить? Собираюсь ли я идти: «Ага! Я помню эту умную маленькую вещь, которую я сделал! Мне не нужно было включать парены, когда я писал это в прошлом году, хорошо, что я помню сейчас!» если это произойдет (или, что еще хуже, кто-то еще, кто не знал об этой хитрости или попал в ситуацию типа «как можно скорее»)?
Разделение с помощью () делает намного более простым быстрое изучение и понимание позже ...
источник
ab = a AND b
?ab
останется неизменным, если нетa AND b
.Общий случай
В C # умножение и деление имеет приоритет над сложением и вычитанием.
Тем не менее, StyleCop, инструмент, который обеспечивает общий стиль для всей кодовой базы с дополнительной целью снизить риск ошибок, связанных с кодом, который может быть недостаточно понятным, имеет правило SA1407 . Это правило будет выдавать предупреждение с таким фрагментом кода:
Понятно, что результат есть
7
и нет9
, но все же StyleCop предлагает поставить круглые скобки:Ваш конкретный случай
В вашем конкретном случае есть приоритет И по сравнению с ИЛИ в конкретном языке, который вы используете.
Это не то, как ведут себя все языки. Многие другие одинаково относятся к И и ИЛИ.
Как разработчик, который работает в основном с C #, когда я впервые увидел ваш вопрос и прочитал фрагмент кода, не читая того, что вы написали ранее, у меня было первое искушение прокомментировать, что эти два выражения не совпадают. Надеюсь, я полностью прочитал весь вопрос, прежде чем комментировать.
Эта особенность и риск того, что некоторые разработчики могут поверить, что AND и OR имеют одинаковый приоритет, делает еще более важным добавление скобок.
Не пишите код с целью показать, что вы умны. Пишите код с целью удобочитаемости, в том числе людьми, которые могут быть не знакомы со всеми аспектами языка.
источник
Как все говорили, используйте круглые скобки каждый раз, когда это делает выражение более читабельным. Однако, если выражение сложное, я бы посоветовал ввести новые функции для подвыражений .
источник
Если вы строго используете язык в единственном числе, может быть. Теперь возьмите все языки, которые вы знаете, от старых до самых современных, от скомпилированных до написания сценариев, до SQL, к вашему собственному DSL, который вы изобрели в прошлом месяце.
Вы помните точные правила приоритета для каждого из этих языков, не глядя?
источник
«Должен ли я использовать круглые скобки в логических утверждениях, даже если в этом нет необходимости».
Да, потому что два человека найдут их полезными:
Следующий программист, чьи знания, компетенция или стиль могут отличаться
Будущее за вами, кто вернется к этому коду на более поздний срок!
источник
Сложные условные обозначения - это «булева алгебра», которую вы пишете в некотором роде, что делает ее почти такой же, как алгебра, и вы определенно использовали бы парены для алгебры , не так ли?
По-настоящему полезными являются правила отрицания:
Или в более понятном формате:
который действительно ясно просто алгебра, когда написано как:
Но мы также можем применить мышление для алгебраического упрощения и расширения:
хотя в коде вы должны написать:
или, в более ясном формате:
По сути, условное выражение по-прежнему является просто алгебраическим выражением, и, четко используя круглые скобки, вы можете с легкостью применять различные алгебраические правила, которые вы уже знаете, к выражению, включая устаревшее понятие «упростить или расширить эту формулу».
источник
!(A + B) <=> !A + !B
и-1*(A + B) = -A + -B
не должен оператор был переворачивается от+
к*
во втором выражении?Я буду использовать круглые скобки, даже если это не обязательно, потому что это помогает лучше понять для всех, для того, кто пишет код, а также для того, кто готов увидеть этот код. В вашем случае даже булевы операторы имеют приоритет, поначалу это может хорошо работать, но мы не можем сказать, что это поможет вам в каждом случае. поэтому я предпочитаю использовать круглые скобки в любых условиях, когда это может потребоваться или по желанию.
источник
Да. Вы должны использовать в любом случае, когда вы чувствуете, что ваш код будет более понятным. Помните, что ваш код должен быть достаточно понятным, чтобы другие могли понять, не читая ваши комментарии внутри кода. Поэтому хорошей практикой является использование скобок и скобок. Также имейте в виду, что это может зависеть от конкретной практики вашей компании / команды. Просто придерживайтесь одного подхода и не смешивайте.
источник