Как проверить равенство? (0 == i) или (i == 0)

Хорошо, мы знаем, что следующие две строки эквивалентны -

  1. (0 == i)
  2. (i == 0)

Кроме того, в прошлом поощрялся первый метод, потому что это позволило бы компилятору выдать сообщение об ошибке, если вы случайно использовали '=' вместо '=='.

Мой вопрос: в сегодняшнем поколении довольно хороших IDE и интеллектуальных компиляторов вы по-прежнему рекомендуете первый метод?

В частности, этот вопрос возник у меня в голове, когда я увидел следующий код -

if (DialogResult.OK == MessageBox.Show("Message")) ... 

На мой взгляд, я бы никогда не рекомендовал вышеизложенное. Есть еще какие-нибудь мнения?

Поскольку это вопрос C, добавьте к нему тег C. Это не проблема C#, Java или Python. AFAIK это только открытый вопрос в C.

S.Lott 29.09.2008 16:27

Это вопрос стиля для любого языка с оператором ==, даже если современные языки не позволят вам спутать i == 0 с i = 0.

Mark Cidade 30.09.2008 04:59

Вот еще одно обсуждение того же: removealldoubt.com/permalink.aspx/…

Marc Gravell 29.09.2008 15:59

@MarkCidade: Я не согласен с этим. Я думаю, вам будет сложно найти кого-то, кто считает, что 0 == i более естественен, чем i == 0 сам по себе. Это произошло исключительно как способ избежать распространенной ошибки.

Ed S. 27.06.2012 03:38

С чем вы не согласны? Стиль программирования может включать в себя то, что кажется вам более естественным, или может иметь больше отношения к старым привычкам, в зависимости от программиста.

Mark Cidade 27.06.2012 04:22
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
22
5
11 023
28
Перейти к ответу Данный вопрос помечен как решенный

Ответы 28

Я думаю, это просто вопрос стиля. И это помогает при случайном использовании оператора присваивания.

Я бы абсолютно не стал просить программиста повзрослеть.

Ответ принят как подходящий

Я предпочитаю второй (i == 0), потому что при его чтении он кажется более естественным. Вы спрашиваете людей: «Вам 21 год или больше?», А не: «21 год меньше или равен вашему возрасту?»

«21 год меньше или равен твоему возрасту?» - это более естественный вопрос для некоторых языков. Многие языки программирования могут выглядеть неопределенно по-английски, но не все кодировщики являются носителями английского языка.

James A. Rosen 29.09.2008 16:25

Не говоря уже о том, что вы ожидаете, что меньшее число будет первым.

Brad Gilbert 30.09.2008 07:23

@Spodi: количество голосов зависит от количества людей, просматривающих тему, и если ответ будет простым / очевидным, больше людей поставят вам +1. Мне бы очень понравилось, если бы я мог получить 100+ голосов за ответ на эзотерический вопрос, относящийся к 8086, но, к сожалению, немногие нажмут на эту тему, и еще меньше узнает, правильно ли я ответил или ошибся. Обновлено: Хорошо, я ответил на комментарий 4-летней давности ...

Ed S. 27.06.2012 03:40

+1, Лично я предпочитаю сравнивать variable == constant. Я всегда пишу значение, которое хочу оценить, слева. Я привык читать слева направо. Если я напишу = вместо ==, я не обращаю внимания, и мне просто нужно отладить.

Nope 05.02.2013 04:46

Все кажется неестественным, пока к этому не привыкнешь ... некоторые люди считают неестественным не использовать malloc, не использовать sizeof *p, не использовать определения типов функций и т. д.

M.M 03.08.2015 10:38

Я бы сказал, что (i == 0) будет звучать более естественно, если вы попытаетесь сформулировать строку на простом (и неоднозначном) английском. Это действительно зависит от стиля программирования программиста или стандартов, которых он должен придерживаться.

Может быть, это не ответ на ваш вопрос. Я пытаюсь использовать === (проверка на идентичность) вместо равенства. Таким образом, преобразование типов не выполняется, и программист вынуждает убедиться, что передан правильный тип,

Лично мне не нравится (1) и всегда нравлюсь (2), однако это меняется для удобочитаемости при работе с диалоговыми окнами и другими методами, которые могут быть очень длинными. Это не выглядит плохо, но если вы развернете MessageBox до его полной длины. Вы должны прокрутить до конца вправо, чтобы выяснить, какой результат вы возвращаете.

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

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

Однако никогда не разговаривайте с коллегой свысока, и намекнув, что это будет вашим поступком, даже в шутку, вы не получите здесь высоких оценок.

Если у вас есть список if, которые не могут быть хорошо представлены переключателем (возможно, из-за языковых ограничений), я бы предпочел посмотреть:

if (InterstingValue1 == foo) { } else
if (InterstingValue2 == foo) { } else
if (InterstingValue3 == foo) { }

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

В частности, на Java я считаю полезным:

if ("SomeValue".equals(someString)) {
}

потому что someString может иметь значение null, и таким образом вы никогда не получите исключение NullPointerException. То же самое применимо, если вы сравниваете константы, которые, как вы знаете, никогда не будут нулевыми, с объектами, которые могут быть нулевыми.

Моя компания только что отказалась от требования делать if (0 == i) из своих стандартов кодирования. Я понимаю, что это имеет большой смысл, но на практике это кажется обратным. Немного жаль, что по умолчанию компилятор C, вероятно, не выдаст вам предупреждение об if (i = 0).

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

Steve Jessop 29.09.2008 15:55

Я согласен с одним из них; -Стена стоит использовать. И, несмотря на название, он не включает все предупреждения, поэтому он не должен вызывать много глупых предупреждений, которые вам, вероятно, наплевать. Используйте -Wall и исправьте свой код, чтобы не получать никаких предупреждений.

Mark Baker 29.09.2008 16:33

В C# не имеет значения, помещаете ли вы переменную первой или последней, потому что присваивания не оцениваются как bool (или что-то, что может быть преобразовано в bool), поэтому компилятор перехватывает любые ошибки, такие как «if (i = 0) CompleteCompanyData.Delete ( ) "

Так что, по крайней мере, в мире C# это вопрос стиля, а не отчаяния. А помещать переменную последней неестественно для англоговорящих. Поэтому для более удобочитаемого кода сначала переменная.

Вау, наверное, я этого не говорил. Нет, подожди, вроде как.

user1228 11.03.2009 14:37

Да, но вы закончили с «для более читаемого кода, сначала переменная».

Nifle 16.03.2009 16:04

Хорошо, я принимаю ваш -1 от имени нации IOnlyReadTheLastSentenceonia.

user1228 16.03.2009 18:31

-1 от меня, так как это явно больше атака на c / C++, чем реальный ответ.

PierreBdR 13.06.2012 12:56

@PierreBdR:: / Я мог бы убрать этот кусок, но я бы оставил комментарий. Верно, эта переменная сначала соответствует тому, как можно было бы говорить. "Один - это количество долларов в вашем кошельке?" это очень неудобный способ спросить: "Может ли братва держать доллар?"

user1228 13.06.2012 17:12

@PierreBdR: Знаешь, я собирался защищать Уилла здесь, потому что не воспринимал это как атаку ... пока не заметил, что вопрос помечен как C и C++. Как здесь вообще уместен ответ, ориентированный на C#?

Ed S. 27.06.2012 03:48

Собственно, пример DialogResult - это то место, где я БЫ рекомендовал этот стиль. Он помещает важную часть if () влево, где ее можно увидеть. Если он находится справа, а у MessageBox больше параметров (что вполне вероятно), вам, возможно, придется прокрутить вправо, чтобы увидеть его.

OTOH, я никогда не видел особого применения в стиле "(0 == i)". Если бы вы могли не забыть поставить константу первой, вы можете не забыть использовать два знака равенства,

Честно говоря, меня лично не интересуют правила для кода, которые нужно прокручивать вправо, чтобы читать, так как я бы все равно запретил это. То, что вы тестируете, важно, и параметры диалогового окна важны: они оба должны быть видны.

Steve Jessop 29.09.2008 15:58

Однако я согласен с вашим вторым абзацем.

Steve Jessop 29.09.2008 16:06

Вопрос не в вспоминая в использовании двух знаков равенства, это в случае опечатки, которую компилятор не может обнаружить, потому что это допустимая конструкция C.

Graeme Perrow 29.09.2008 17:15

@Graeme: конечно, но один из способов отловить опечатки - это посмотреть, как вы их печатаете. Другой - конечно, включить предупреждения компилятора. -Wall -Ошибка и бинго !, ваш компилятор может отлавливает его, даже если он действителен C :-)

Steve Jessop 29.09.2008 17:40

Я, конечно, согласен с предупреждениями. Это просто звучало так, как будто вы говорили: «Чтобы избежать опечаток, не следует вводить что-то неправильно», что не очень помогает. :-)

Graeme Perrow 29.09.2008 21:06

Я всегда использую второй метод. В C# написание

if (i = 0) {
}

в любом случае приводит к ошибке компилятора (невозможно преобразовать int в bool), так что вы можете сделать ошибку, на самом деле не проблема. Если вы тестируете bool, компилятор все равно выдает предупреждение, и вам не следует сравнивать bool с true или false. Теперь вы знаете почему.

оба равны, хотя я бы предпочел вариант 0 == i.

при сравнении строк более подвержено ошибкам сравнение MyString .equals (getDynamicString ())

поскольку getDynamicString () может вернуть значение null. чтобы быть более константным, напишите 0 == i

Ну, это зависит от языка и рассматриваемого компилятора. Контекст - это все.

В Java и C# опечатка «присвоение вместо сравнения» заканчивается недопустимым кодом, за исключением очень редкой ситуации, когда вы сравниваете два логических значения.

Я могу понять, почему можно использовать «безопасную» форму в C / C++, но, честно говоря, большинство компиляторов C / C++ предупредят вас, если вы все равно сделаете опечатку. Если вы используете компилятор, который этого не делает, спросите себя, почему :)

Вторая форма (переменная, а затем константа), на мой взгляд, более читабельна - поэтому я использую ее везде, где она определенно не вызовет проблем.

FYI - назначение в операторе if технически законно java (к сожалению).

Sean Reilly 16.06.2009 09:08

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

Jon Skeet 16.06.2009 09:16

if (someOp = true) {...} приходит на ум - хотя это, конечно, плохой тон по любому количеству причин.

Sean Reilly 16.06.2009 09:29

Точно. Я избегаю этого по другим причинам, поэтому тот факт, что это случайное задание, теряет значение.

Jon Skeet 16.06.2009 10:40

Я предпочитаю (i == 0), но я все еще как бы создаю для себя «правило» (0 == i), а затем каждый раз нарушаю его.

«А?», - думаете вы.

Что ж, если я принимаю осознанное решение поместить lvalue слева, тогда я уделяю достаточно внимания тому, что я печатаю, чтобы заметить, набираю ли я «=» вместо «==». Я надеюсь. В C / C++ я обычно использую -Wall для своего собственного кода, который в любом случае генерирует предупреждение в gcc для большинства ошибок "=" для "==". Я не помню, чтобы видел это предупреждение в последнее время, возможно потому, что чем дольше я программирую, тем более рефлексивно параноидально я отношусь к ошибкам, которые делал раньше ...

if (DialogResult.OK == MessageBox.Show("Message"))

мне кажется ошибочным. Суть уловки - избежать случайного назначения чего-либо.

Но кто должен сказать, будет ли DialogResult.OK с большей или меньшей вероятностью оценивать присваиваемый тип, чем MessageBox.Show ("Сообщение")? В Java вызов метода не может быть назначен, тогда как поле может быть не окончательным. Так что, если вы беспокоитесь о том, чтобы ввести = for ==, на самом деле в Java для этого примера должно быть наоборот. В C++ ни один из них или оба не могут быть назначены.

(0 == i) полезно только потому, что вы абсолютно уверены, что числовой литерал никогда не назначается, тогда как i может быть.

Когда обе стороны вашего сравнения назначаются, вы не можете защитить себя от случайного назначения таким образом, и это происходит, когда вы не знаете, какое из них можно назначить, не глядя на него. Нет никакого волшебного трюка, который гласил бы: «Если вы воспользуетесь интуитивно понятным способом, вы будете в безопасности». Хотя, полагаю, это привлекает внимание к проблеме, как и мое правило «всегда нарушать правила».

Вы знаете, я всегда использую формат условного выражения если (я == 0), и моя причина для этого заключается в том, что я пишу большую часть своего кода на C# (который в любом случае будет отмечать другой), и я использую подход, основанный на тестировании, для моей разработки и моей тесты обычно так или иначе выявляют эту ошибку.

Я работал в магазинах, где пытались навязать формат 0 == i, но мне было неудобно писать, неудобно запоминать, и в конечном итоге он стал пищей для обозревателей кода, которые искали низко висящие плоды.

Я стараюсь всегда использовать 1-й случай (0 == i), и это несколько раз спасло мне жизнь!

Мы можем продолжать и продолжать говорить о том, насколько хороши наши IDE, но я все еще шокирован количеством людей, которые снижают уровни предупреждений в своих IDE.

Следовательно, для меня всегда лучше просить людей использовать (0 == i), поскольку вы никогда не знаете, какой программист что делает. Лучше перестраховаться, чем сожалеть

Зачем тому, кто забывает использовать == вместо =, не забывать об этом?

Mark Baker 29.09.2008 16:35

Я лично предпочитаю использовать формат переменной-операнда-значения отчасти потому, что я использую его так долго, что он кажется «естественным», а отчасти потому, что он кажется преобладающим соглашением. Есть некоторые языки, которые используют операторы присваивания, например следующие:

:1 -> x

Поэтому в контексте этих языков может быть довольно сложно увидеть следующее, даже если оно действительно:

:if (1=x)

Так что это тоже нужно учитывать. Я согласен с тем, что ответ окна сообщения является одним из сценариев, в котором использование формата значение-операнд-переменная работает лучше с точки зрения удобочитаемости, но если вы ищете постоянство, вам следует отказаться от его использования.

  1. (0 == я)

Я всегда выберу этот. Это правда, что большинство современных компиляторов не позволяют присваивать переменную в условном выражении, но правда в том, что некоторые это делают. При программировании для Интернета сегодня мне приходится использовать в системе множество языков. Используя 0 == i, я всегда знаю, что условное выражение будет правильным, и я не полагаюсь на компилятор / интерпретатор, чтобы поймать мою ошибку за меня. Теперь, если мне нужно перейти с C# на C++ или JavaScript, я знаю, что мне не придется отслеживать ошибки присваивания в условных операторах в моем коде. Для чего-то такого маленького и сэкономить столько времени - это и ежу понятно.

Это одна из моих самых больших неприятностей. Нет причин снижать удобочитаемость кода (if (0 == i), что? Как может измениться значение 0?), Чтобы уловить то, что любой компилятор C, написанный за последние двадцать лет, может уловить автоматически.

Да, я знаю, большинство компиляторов C и C++ не включают это по умолчанию. Найдите нужный переключатель, чтобы включить его. Нет оправдания незнанию своих инструментов.

Это действительно действует мне на нервы, когда я вижу, как он проникает на другие языки (C#, Python), которые в любом случае обычно помечают это!

Третий вариант - полностью запретить присваивание внутри условных выражений:

В ситуациях с высокой надежностью вам не разрешается (без хороших объяснений в предшествующих комментариях) назначать переменную в условном операторе - это полностью устраняет этот вопрос, потому что вы либо выключаете его в компиляторе, либо с помощью LINT и только в очень контролируемых ситуациях. вам разрешено использовать это.

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

Таким образом, другой вариант - просто запретить такие операторы и, где необходимо, использовать комментарии, чтобы отключить проверку LINT для этой распространенной ошибки.

-Адам

Проблема не в этом. Проблема в том, что все мы иногда допускаем опечатки и по ошибке используем = вместо ==.

Ferruccio 29.09.2008 16:39

Точно. Когда вы набираете = вместо ==, компилятор и / или lint выдадут вам ошибку - вам не будет разрешено создать этот код непреднамеренно или намеренно.

Adam Davis 29.09.2008 18:16

Я использую (i == 0) по той простой причине, что он лучше читается. Это очень плавно течет в моей голове. Когда вы читаете код обратно себе для отладки или других целей, он просто течет как чтение книги и имеет больше смысла.

Правило 0 для всех стандартов кодирования должно заключаться в том, чтобы «писать код, который может быть легко прочитан другим человеком». По этой причине я использую (наиболее быстро меняющееся значение) тестовое значение (менее быстро меняющееся значение или константа), то есть в данном случае «i == 0».

Даже там, где этот метод полезен, правило должно заключаться в том, чтобы «не помещать lvalue слева от сравнения», а не «всегда помещать любую константу слева», как это обычно интерпретируется - например, нет ничего быть полученным от написания

if (DateClass.SATURDAY == dateObject.getDayOfWeek())

если getDayOfWeek () все равно возвращает константу (и, следовательно, не lvalue)!

Мне повезло (по крайней мере в этом отношении) в том, что в наши дни я в основном кодирую на Java и, как уже упоминалось, if (someInt = 0) не компилируется.

Предостережение относительно сравнения двух логических значений - это немного отвлекающий маневр, поскольку большую часть времени вы либо сравниваете две логические переменные (в этом случае их замена не помогает), либо проверяете, установлен ли флаг, и горе -betide-вы, если я поймаю, что вы сравниваете что-либо явно с правда или ложный в ваших условных выражениях! Гррр!

Раньше я был убежден, что более читаемый вариант (i == 0) - лучший вариант.

Затем у нас проскочила производственная ошибка (к счастью, не моя), где проблема заключалась в ошибке типа ($ var = SOME_CONSTANT). Клиенты начали получать электронную почту, предназначенную для других клиентов. Данные конфиденциального типа также.

Вы можете утверждать, что Q / A должен был это уловить, но они этого не сделали, это другая история.

С того дня я всегда настаивал на версии (0 == i). Это в основном снимает проблему. Это кажется неестественным, поэтому вы обращаете внимание, чтобы не совершить ошибку. Здесь просто невозможно ошибиться.

Также намного легче заметить, что кто-то не отменил оператор if при проверке кода, чем то, что кто-то случайно присвоил значение в if. Если формат является частью стандартов кодирования, люди его ищут. Люди обычно не отлаживают код во время проверки кода, и кажется, что глаз просматривает (i = 0) против (i == 0).

Я также гораздо больший поклонник java "Constant String" .equals (dynamicString), отсутствие исключений нулевого указателя - это хорошо.

Ты только что обратил меня. Сейчас я меняю свои стандарты.

Remian8985 10.08.2015 03:20

Мой опыт противоположен: я вижу, что там, где используется нотация Йоды, она, как правило, используется не только в тех случаях, когда она может улавливать = / == опечатки, но также и для других, например, if (42 <= result). Дополнительная сложность обратной записи привела к ошибкам, которые не могли быть обнаружены статической проверкой - в отличие от сценариев = / ==, для которых существуют статические проверки, и даже редакторы в настоящее время могут быть настроены для выделения таких строк.

Dirk Herrmann 19.07.2019 22:38

В C - да, но вы уже должны были включить все предупреждения и выполнять компиляцию без предупреждений, и многие компиляторы C помогут вам избежать этой проблемы.

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

Читаемость кода - одна из самых важных вещей для кода размером более нескольких сотен строк, и определенно i == 0 читается намного легче, чем наоборот.

if (DialogResult.OK == MessageBox.Show("Message")) ...

Я бы рекомендовал всегда написать сравнение таким образом. Если результат MessageBox.Show ("Message") может быть нулевым, вы рискуете получить NPE / NRE, если сравнение будет наоборот.

Математические и логические операции не рефлексивны в мире, который включает NULL.

ну ладно, не в C# и не с '==' вместо .equals ... но вот откуда взялась привычка.

Sean Reilly 16.06.2009 09:03

Для функциональности не имеет значения, в каком направлении идет сравнение. Одним из преимуществ такого подхода является то, что OK хорошо виден, а не за много миль вправо (возможно, даже за кадром).

M.M 03.08.2015 10:37

Я считаю, что единственный фактор, который когда-либо заставляет одно над другим, - это если цепочка инструментов не предоставляет предупреждения для перехвата назначений в выражениях. Мои предпочтения как разработчика не имеют значения. Для выражения лучше всего подходит четкое представление бизнес-логики. Если (0 == i) более подходит, чем (i == 0), я выберу его. В противном случае я выберу другой.

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

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