Какую сторону (слева или справа) оператора (и) оценивается в C ++

StackOverflow https://stackoverflow.com/questions/2102907

Вопрос

Какой заказ оценивает оператор и &&

Например, следующий код

if (float alpha = value1-value2 && alpha > 0.001)
    //do something

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

Есть идеи?

Спасибо

Это было полезно?

Решение

Это проанализируется как:

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

По той же причине.

Чтобы достичь того, что вы есть буквально Пытаясь выразить, вы должны либо предварительно деклар alpha

int alpha;
if ((alpha = value1 - value2) && alpha > 0.001) {
  // whatever 
}

или разделить if в два

if (int alpha = value1 - value2) 
  if (alpha > 0.001) {
    // whatever 
  }

Однако, поскольку второе условие уже требует alpha быть больше, чем 0, не имеет большого смысла даже проверить первую, поэтому самое значимое, что нужно сделать, - это просто уменьшить все это.

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))

После разъяснения, как это работает (для образовательных целей), не делайте этого. Анкет Не смешивайте инициализацию/присвоение переменной переменной и сравнения в одном и том же операторе.

Лучше, если каждое утверждение является либо «командой», либо только «запрос».

И это намного, намного лучше, если условие внутри «если» очень четко читаемо, и однозначно. Не целое число, нет ничего, просто бул.

Первая часть вашего состояния - целое число. Тогда вы делаете и с лондоном. Вы заставляете конверсию без необходимости вообще. Дайте, если и условные операторы именно то, о чем они просят: Bools.

Отвечая на вопрос в названии, это зависит от типов операндов.

Для встроенных типов, && Короткие замыкания, что означает, что LHS оценивается, и если он ложный, то RHS вообще не оценивается.

Для пользовательских типов, которые перегружены operator&&, это не короткое замыкание. Обе стороны оцениваются в неопределенном порядке, а затем вызывается функция.

Я думаю, что другие ответили на вопрос, на который вам нужно ответить.

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

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

Он оценивается слева направо.

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

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 alpha;
if ((alpha=value1-value2) && alpha>0.001)

Но я не думаю, что это делает то, что вам нужно. У вас есть Альфа как int, и вы затем сравниваете ее с плавающей значением. Первая часть оператора && оператора будет повторно повторно, пока альфа не будет равна нулю, а вторая часть вернет истину, если Альфа больше 0. Так что вы, вероятно, должны сделать это

int alpha;
if ((alpha=value1-value2)>0)

или для гораздо более читаемого кода

int alpha=value1-value2
if (alpha>0)

Но чтобы ответить на ваш первоначальный вопрос: && выполнен слева направо и короткометражным, когда ответ очевиден. Т.е., если первая часть && является ложной, вторая даже не провалена!

Вот статья ПРИМЕР ИСПРАВЛЕНИЯ Оператора и ассоциативность.

Из того, что я могу сказать, ваше намерение состоит в том, чтобы объявить временное, присвоить ему значение значения1-Value2, затем протестируйте результат и введите блок, если он больше, чем какое-то значение. alpha объявляется как Int, но вы, кажется, сравниваете его с двойником. Альфа должна быть двойной.

Вы проявляете творческий подход с использованием временных. Ясно часто лучше, чем мило. Сделайте это вместо этого:

double alpha = value1-value2;
if (alpha > 0.001)

Согласно с :http://en.wikipedia.org/wiki/operatorators_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)))

Как написано, это выражение делает следующее:

  1. Оценивает value1 - value2 и преобразует это в bool путем неявного сравнения с нулем - т.е. это эффективно (value1 - value2) != 0
  2. Оценивает alpha > 0.001 после усечения 0.001 к int(0). В этот момент alpha не инициализируется.
  3. Рассчитывает Логично и из двух предыдущих оценок
  4. Преобразует логический результат Логично и Вернуться к целому числу

Я думаю, что это суммирует остальные посты. Единственная причина, по которой я опубликовал отдельный ответ, заключается в том, что я не мог найти ту, которая упомянула оба, когда alpha не был инициализирован, и все преобразования, которые происходят здесь; Ответ Уоллика ближе всего.

Конечно, остальные ответы, которые предполагают, что вы используете скобки и отдельное объявление о alpha именно то, что вы должны сделать, чтобы исправить это. Объявление переменных в if Заявление является частью языка, который я не нашел хорошего использования - объявления в рамках повторных структур кажется более уместным.

Проблема в том, что утверждение оценивает так:

if (int alpha = (value1-value2 && alpha > 0.001))

Используйте скобки, чтобы исправить левую и правую сторону оператора &&:

if ((int alpha = value1-value2) && (alpha > 0.001))

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top