== Оператор и операнды - PullRequest
       44

== Оператор и операнды

5 голосов
/ 24 марта 2009

Я хочу проверить, равно ли значение 1. Есть ли разница в следующих строках кода

Оценочное значение == 1

1 == оценочное значение

с точки зрения исполнения компилятора

Ответы [ 12 ]

17 голосов
/ 24 марта 2009

В большинстве языков это одно и то же.

Люди часто делают 1 == оцененное значение, потому что 1 не является lvalue. Это означает, что вы не можете случайно выполнить задание.

Пример:

if(x = 6)//bug, but no compiling error
{
}

Вместо этого вы можете вызвать ошибку компиляции вместо ошибки:

if(6 = x)//compiling error
{
}

Теперь, если x не имеет тип int и вы используете что-то вроде C ++, тогда пользователь мог создать переопределение оператора == (int), которое переносит этот вопрос в новое значение. 6 == x не будет компилироваться в этом случае, но x == 6 будет.

9 голосов
/ 25 марта 2009

Зависит от языка программирования.

В Ruby, Smalltalk, Self, Newspeak, Ioke и многих других объектно-ориентированных языках программирования с одной диспетчеризацией a == b на самом деле является отправкой сообщения. Например, в Ruby это эквивалентно a.==(b). Это означает, что когда вы пишете a == b, выполняется метод == в классе a, но когда вы пишете b == a, выполняется метод в классе b. Так что, очевидно, не одно и то же:

class A; def ==(other) false end; end
class B; def ==(other) true  end; end

a, b = A.new, B.new

p a == b # => false
p b == a # => true
5 голосов
/ 24 марта 2009

Зависит от языка.

5 голосов
/ 24 марта 2009

Нет, но последний синтаксис выдаст вам ошибку компилятора, если вы случайно наберете

if (1 = evaluatedValue)

Обратите внимание, что сегодня любой порядочный компилятор предупредит вас, если вы напишите

if (evaluatedValue = 1)

так что это в основном актуально по историческим причинам.

3 голосов
/ 24 марта 2009

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

Таким образом, X = 3 объединит переменную X и значение 3, тогда как 3 = X попытается объединить постоянную 3 с текущим значением X и будет эквивалентно assert(x==3) в императивных языках.

2 голосов
/ 24 марта 2009

В общем, вряд ли имеет значение, используете ли вы, Оценочное значение == 1 ИЛИ 1 == оценочное значение.

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

И снова я хотел бы процитировать известный сценарий сравнения строк в Java. Рассмотрим строку String, которую нужно сравнить с другой строкой «SomeString».

str = getValueFromSomeRoutine();

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

if(str!=NULL)
{
   if(str.equals("SomeString")
   {
      //do stuff
    }
}

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

if ("SomeString".equals(str))
{
   //do stuff
}

Хотя это менее читабельно, что опять-таки зависит от контекста, это сэкономит вам лишнее, если.

2 голосов
/ 24 марта 2009

Это то же самое

1 голос
/ 24 марта 2009

Иногда в C ++ они делают разные вещи, если вычисляемое значение относится к типу пользователя и определен оператор ==. Нехорошо.

Но это очень редко причина, по которой кто-то выбирал бы один способ перед другим: если оператор == не является коммутативным / симметричным, в том числе если тип значения имеет преобразование из int, то у вас есть проблема, которая, вероятно, исправление, а не работа вокруг. Ответ Брайана Р. Бонди и других, вероятно, не дает понять, почему кто-то беспокоится об этом на практике.

Но факт остается фактом: даже если оператор == является коммутативным, компилятор может не делать точно одно и то же в каждом случае. Он (по определению) вернет тот же результат, но может сделать что-то в несколько ином порядке, или как угодно.

1 голос
/ 24 марта 2009

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

Например, для компиляторов GNU вы делаете это с флагом -S. Для компиляторов VS наиболее удобный способ - запустить тестовую программу в отладчике, а затем использовать представление отладчика ассемблера.

0 голосов
/ 24 марта 2009

В языках Си обычно сначала ставят постоянное или магическое число, чтобы, если вы забыли один из «=» проверки на равенство (==), компилятор не интерпретировал это как присваивание.

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

...