Какая сторона (левая или правая) оператора & & (и) вычисляется в C++
В каком порядке вычисляется оператор and & &
Например следующий код
if (float alpha = value1-value2 && alpha > 0.001)
//do something
Выдал исключение, что Альфа используется без инициализации. Я думал, что выражение слева от && всегда будет инициировать значение alpha первым, но, похоже, я могу ошибаться
Есть идеи?
Спасибо
14 ответов:
Это разбирается следующим образом:
if (int alpha = (value1-value2 && (alpha > 0.001)))... потому что
&&имеет более высокий "приоритет разбора", чем=- что, вероятно, не то, что вы хотите. Попробуйте:int alpha = value1-value2; if (alpha && (alpha > 0.001))
Суть здесь в том, что то, что вы пытаетесь выразить, не может быть выражено одним логическим условием с включенным в него объявлением
alpha(несмотря на то, что некоторые другие ответы утверждают).Другие ответы уже объясняли вам, что ваше условие не анализируется так, как вы думаете, хотя многие ответы делают очевидную ошибку, ссылаясь на приоритет оператора
=в условии, в то время как в действительности нет оператора=там вообще ничего нет. Правильное объяснение состоит в том, что при объявлении переменной в условииifсинтаксис является синтаксисом объявления с инициализатором, поэтому все это анализируется так же, как иint alpha = value1 - value2 && alpha > 0.001;Будет проанализировано, т. е. это объявление
int alpha, инициализированноеvalue1 - value2 && alpha > 0.001. В нем нет оператора=. И я надеюсь, теперь вы понимаете, почему компилятор говорит, что Вы читаете неинициализированную переменную в выражении инициализатора. Компилятор сделал бы то же самое жалоба на следующее заявлениеПо той же самой причине.int alpha = alpha; // reading uninitialized variableЧтобы достичь того, что вы буквально пытаетесь выразить, вы должны либо предварительно объявить
alphaint alpha; if ((alpha = value1 - value2) && alpha > 0.001) { // whatever }Или разделите ваш
ifна дваОднако, поскольку второе условие уже требует, чтобыif (int alpha = value1 - value2) if (alpha > 0.001) { // whatever }alphaбыло больше, чем0, не имеет большого смысла даже проверять первое, поэтому наиболее значимым было бы просто уменьшить все это toКонечно, как уже отмечали другие, сравнение значенияint alpha = value1 - value2; if (alpha > 0.001) { // whatever }intс0.001является допустимой, но довольно странной вещью. Просто сделайint alpha = value1 - value2; if (alpha > 0) { // whatever }
Левая сторона всегда оценивается первой. Проблема здесь заключается в приоритете операторов. Смотрите, если это не работает лучше:
if ((int alpha = value1-value2) && (alpha > 0.001))
После разъяснения того, как это работает (в воспитательных целях), Не делайте этого. Не смешивайте инициализацию/присвоение переменных и сравнения в одном и том же операторе.
Лучше, если каждый оператор является либо "командой", либо "запросом" в отдельности.
И гораздо, гораздо лучше, если условие внутри "если" очень ясно читается и однозначно bool. Не целое число, нет ничего, просто бул.
Первая часть вашего условия-целое число. Затем вы делаете и с a тип bool. Вы принуждаете к обращению без всякой необходимости. Дайте if и условным операторам именно то, что они просят: bools.
Отвечая на вопрос в заголовке, он зависит от типов операндов .
Для встроенных типов,
&&короткие замыкания, что означает, что LHS оценивается, и если это ложно, то RHS не оценивается вообще.Для пользовательских типов, которые перегружены
Хотя я думаю, что другие справились с вопросом, на который вам нужно ответить.operator&&, это не короткое замыкание. Обе стороны вычисляются в неопределенном порядке, а затем вызывается функция.
Если я не ошибаюсь, эта операция не определена. Указание на переменную to, а затем ссылка на эту же переменную в одном операторе не определены.
Он оценивается слева направо.
В вашем случае, однако, назначение-это последнее, что произойдет, и все они будут вести себя так (где Альфа используется как часть вычисления, чтобы получить результат для его инициализации):
if (int alpha = (value1-value2 && alpha > 0.001))Вы не можете смешивать объявления переменных в сложные выражения, поэтому следующее не будет компилироваться:
if ((int alpha = value1-value2) && (alpha > 0.001))Поэтому вам нужно разбить его на две строки:
int alpha = value1 - value2; if (alpha > 0.001)
if (int alpha = value1-value2 && alpha > 0.001)В соответствии с правила будут оцениваться в порядке
1. (value1-value2) [evaluate subtraction] 2. && (left side) [test left side] 3. (alpha > 0.001) [evaluated only if value-value2 != 0] 4. && (right side) [test right side] 4. alpha = [assignment]На Шаге 3 сначала оценивается Альфа. Поскольку он не был назначен-и, возможно, не объявлен, правила не ясны на этот счет-он производит ошибку.
Недостаток состоит в том, что назначение имеет более низкий приоритет, чем&&. Что еще не работает, но уже ближе:if (int alpha = value1-value2, alpha > 0.001)Gcc дает
error: expected expression before ‘int’. Ну, может быть, и не ближе. С первоначальным утверждением gcc говорит то же самое.
Я предполагаю, что это потому, что вы объявляете хранилище внутри оператора "if". Я даже не думал, что это будет компилироваться.
Попробуйте это.
Но я не думаю, что это делает то, что вам нужно. У вас есть альфа в качестве int, и вы затем сравниваете его со значением с плавающей запятой. Первая часть оператора && будет повторять true, пока альфа не равна нулю, а вторая часть будет возвращать true, если альфа больше 0. Так что вам, наверное, стоит сделать этоint alpha; if ((alpha=value1-value2) && alpha>0.001)int alpha; if ((alpha=value1-value2)>0)Или для гораздо более читаемого кода
Но чтобы ответить на ваш первоначальный вопрос: & & выполняется слева направо и замыкается, когда ответ очевиден. То есть, если первая часть && ложна, то вторая даже не уклоняется!int alpha=value1-value2 if (alpha>0)
Вот статья , перечисляющая приоритет операторов и ассоциативность.
Из того, что я могу сказать, ваше намерение состоит в том, чтобы объявить временное, присвоить ему значение value1-value2, затем проверить результат и ввести блок if, если он больше некоторого значения.alphaобъявляется как int, но вы, кажется, сравниваете его с двойником. Альфа должен быть двойником.Ваше творчество с использованием временных средств. Ясный часто лучше, чем милый. Сделать это вместо этого:
double alpha = value1-value2; if (alpha > 0.001)
Согласно : http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B
- LtR > LtR && LtR = RtLУчитывая Ваш пример
(int alpha = value1-value2 && alpha > 0.001) (int alpha = (value1-value2) && alpha > 0.001) (int alpha = (value1-value2) && (alpha > 0.001)) (int alpha = (value1-value2) && (alpha > 0.001)) (int alpha = ((value1-value2) && (alpha > 0.001)))
Как написано это выражение делает следующее:
- вычисляет
value1 - value2и преобразует его вboolпутем неявного сравнения с нулем-т. е.]}- вычисляет
alpha > 0.001после усечения0.001доint(0). в этот моментalphaне инициализируется.- вычисляет логические и из двух предыдущих оценок
- преобразует Булев результат логического и обратно в целое число
I думаю, что это обобщает остальные сообщения. Единственная причина, по которой я опубликовал отдельный ответ, заключается в том, что я не смог найти тот, который упоминал бы оба, Когда
Конечно, остальные ответы, которые предполагают, что вы используете скобки и отдельное объявлениеalphaне был инициализирован, и все преобразования, которые происходят здесь; ответ уоллика ближе всего.alpha, - это именно то, что вы должны сделать, чтобы исправить это. Объявление переменных в оператореifявляется частью язык, для которого я не нашел хорошего применения - объявления в рамках структур повторения, кажется более подходящим.