++ операнд не работает, если var=var++;

Из старых времен я узнал, что ++ означает постепенное добавление к значению целого числа. если ++var, он сначала добавит единицу, а затем присвоит ее значению, а если var++, то добавит единицу позже.

Вот мой вопрос:

int step=0;
if(conditon==true){
    while(!end ){
        step=step++;
    }
}
     System.out.println(step);

Вывод этого небольшого фрагмента кода будет нулевым. Но если я заменю step=step++; на step=++step;, это даст правильный ответ.

Однако я смущен, почему есть разница?

ИЗМЕНИТЬ

Разница с упомянутым ответом: есть 2 (или даже 3) разных переменных, которые назначаются друг другу, в то время как здесь step = step ++ приведет к 0. Основываясь на ответах на этот вопрос, он будет другим. но это не так. Зачем?

Вот ответ на этот вопрос:

int x = 0;
int y = 0;
y = ++x;            // result: y=1, x=1

int x = 0;
int y = 0;
y = x++;            // result: y=0, x=1

в соответствии с этим step=step++ должно составлять в сумме step (поскольку и x, и y здесь - одна и та же переменная, которая является шагом), но это не так.

ИЗМЕНИТЬ 2

Есть кое-что более запутанное. Если заменить step=step++ на step++, то получится то же самое, что и step=++step, что меня еще больше сбивает с толку.


person lonesome    schedule 22.11.2015    source источник
comment
В частности, этот ответ объяснит детали   -  person Wand Maker    schedule 22.11.2015
comment
@WandMaker нет, не было. в этих ответах есть 2 разные переменные, которые назначаются друг другу, а здесь step=step++ приведет к 0. В зависимости от ответов на этот вопрос он будет другим. но это не так. Зачем?   -  person lonesome    schedule 22.11.2015
comment
Внимательно перечитайте его, объясните, в какой байт-код (и, следовательно, в псевдо-код Java) будет переведено y = y++. Поэтому у вас есть порядок инструкций и четкое объяснение результатов, которые вы получите.   -  person benzonico    schedule 22.11.2015
comment
@benzonico, но в конце концов он добавляет один к y. Следовательно, в конце моего кода то же самое должно произойти с step, чего не происходит.   -  person lonesome    schedule 22.11.2015
comment
вам нужно разбить то, что делает операция. y = x ++; — это int t = x; x++; y = t;, а step = step++; — это int t = step; step++; step = t;, поэтому он не должен изменять step, поскольку он перезаписывается, чего не происходит в случае x и y.   -  person Peter Lawrey    schedule 22.11.2015
comment
Он не добавляет в конце концов к y, а добавляет 1 перед присваиванием.   -  person Peter Lawrey    schedule 22.11.2015
comment
@PeterLawrey, но ++x is called preincrement while x++ is called postincrement. , поэтому он должен сначала выполнить задание, а затем добавить. точно так же, как все программисты обычно делают в цикле for как i++. В общем, вы имеете в виду, что step++ даст другой результат? который он сделал, дает те же результаты, что и step=++step. теперь я немного запутался.   -  person lonesome    schedule 22.11.2015
comment
@lonesome это приращение поста. т. е. после получения значения не публикуется все. Присваивание всегда происходит последним.   -  person Peter Lawrey    schedule 22.11.2015
comment
@PeterLawrey, тогда я думаю, что все время ошибался в своих мыслях. мысль до и после относится к заданию. Тем не менее, вы не ответили на вторую часть моего последнего комментария.   -  person lonesome    schedule 22.11.2015
comment
@lonesome step++ не дает другого результата. но step=step++; или i=i++ будут.   -  person Peter Lawrey    schedule 22.11.2015
comment
@PeterLawrey Я имел в виду, что сравнение step=step++ только с step++ дает разные результаты, хотя оба используют один и тот же инкрементный операнд.   -  person lonesome    schedule 23.11.2015
comment
@lonesome один выполняет задание после приращения, а другой нет. Код не тот же, поэтому вы должны ожидать, что он будет делать что-то другое.   -  person Peter Lawrey    schedule 23.11.2015


Ответы (3)


я разделил ваше условие на простой следующий код:

  int step=0;
  step=step++;           
  System.out.println(step); // will give 0

Причина, по которой это дает 0 в качестве вывода, заключается в том, что увеличенное значение никогда не присваивается step.

для step=step++; вот что происходит

int temp = 0;
step = temp; // step will get 0
temp = temp +1; // while temp is incremented

в случае ++step вышеуказанное меняется на

int temp =0 ;
temp = temp + 1; // temp gets incremented
step =temp; // step gets the  incremented value
person Ramanlfc    schedule 22.11.2015
comment
Что насчет step++? Я имею в виду просто step++ и результат такой же, как step=++step. Мой вопрос: Почему?. - person lonesome; 22.11.2015
comment
@lonesome я предоставил оба случая - person Ramanlfc; 22.11.2015
comment
@lonesome только для шага ++, увеличенное значение temp будет присвоено step, но если вы напишете значение step=step++;, оно будет назначено до увеличения - person Ramanlfc; 22.11.2015
comment
В своем ответе вы не указали, когда это только step++. Итак, что насчет ++step? имеет ли это тот же результат, что и step++? Мой другой вопрос: почему, когда мы явно назначаем шаг ++ для шага, он не назначает его, но когда мы просто пишем шаг ++, он это делает? есть какая-то особая причина? - person lonesome; 22.11.2015
comment
@lonesome я указал ++step в ответе и всего за step++ прочитал комментарий - person Ramanlfc; 22.11.2015
comment
расслабляться. не легко рассердиться. то, что я говорил, касается только step++ и только ++step, если они разные, а также почему существует разница между step=step++ и просто step++? - person lonesome; 22.11.2015

step++ и ++step сами по себе увеличивают значение шага, но они дают разные значения. step++ оценивается как увеличенное значение, ++step оценивается как не увеличенное значение.

step = step++ увеличивает шаг, а затем присваивает шагу не увеличенное значение.

step = ++step увеличивает шаг, а затем присваивает шагу увеличенное значение.

Таким образом, step = step++ увеличивает шаг, но затем возвращает его к исходному значению, из-за чего оператор не имеет никакого эффекта.

person fgb    schedule 22.11.2015
comment
что вы имеете в виду, когда говорите evaluates to the incremented value и evaluates to the non-incremented value? - person lonesome; 22.11.2015
comment
@lonesome Если шаг был равен 1, то после его увеличения увеличенное значение равно 2, а не увеличенное значение равно 1. Это значение, которое используется, когда вы его назначаете или используете в выражении. - person fgb; 22.11.2015

Разница в поведении связана с поведением двух разных операторов, которые вы используете. ++ перед переменной — это префиксный оператор, а ++ после переменной — постфиксный оператор. Два разных оператора изменяют переменную в два разных момента во время вычисления выражения. См. этот stackoverflow В чем разница между префиксными и постфиксными операторами? < /а>

Когда вы выполняете присваивание, оцениваются операции справа от оператора присваивания (знак равенства или =), а результат помещается в переменную слева от оператора присваивания.

Операции в правой части оцениваются или вычисляются с использованием различных правил приоритета операций. См. этот stackoverflow Приоритет оператора в Java.

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

Как префиксные, так и постфиксные операторы имеют почти наивысший приоритет в Java, как и в большинстве языков. Это означает, что если круглые скобки не используются для изменения последовательности вычислений, префиксные и постфиксные операторы будут одними из первых оцениваемых операторов. См. Таблицу приоритета операторов Java, где представлена ​​краткая и простая шпаргалка.

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

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

Легче увидеть, что происходит, используя две переменные, а не одну:

int  a, b;

a=0;
b = ++a;  // increment a and assign the new value of variable a to variable b
b = a++;  // increment a and assign the old value of variable a to variable b

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

С оператором префикса правая часть вычисляет новое увеличенное значение переменной a. При использовании постфиксного оператора правая часть вычисляет старое значение переменной a до того, как оно будет увеличено постфиксным оператором.

Часто, когда требуется просто увеличить переменную, в отдельном операторе используется префикс или постфикс ++.

int a = 0;

a = a + 1;   // increment a by adding 1 to the value and assigning new value to a
a += 1;  // increment a by using += operator
a++;   // increment a by using postfix ++ operator
++a;   // increment a by using the prefix ++ operator

В операторах выше, где используется оператор ++, ничего не делается с результатом операции. Таким образом, переменная a увеличивается, однако старое значение a из постфиксного оператора или новое значение a из префиксного оператора ни для чего не используются. Единственным результатом использования этих операторов является увеличение переменной a.

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

person Richard Chambers    schedule 22.11.2015