2014-11-22 10 views
3

От страницы 280 OCP Java SE 6 Программист Practice Exams, вопрос 9:x = x ++ не увеличивается, потому что ++ применяется после назначения?

int x = 3; 
x = x++; 
// x is still 3 

В объяснении мы можем прочитать, что:

x = x++; линия не оставляет x == 4 оскольку ++ является применяется после присвоение произошло.

Я согласен с тем, что x равно 3, я понимаю пост-инкремацию.

Я не согласен с объяснением. Я бы заменил «после» с «до».

Я думал, что это работает так:

  1. x является 3.
  2. x++ выполняется. Я вижу этот оператор пост-приращение как функции:

    int operator++() { 
        int temp = getX(); 
        setX(temp + 1); 
        return temp; 
    } 
    

    Таким образом, после x++ исполнения, x составляет 4, но возвращаемое значение из x++ выражения 3.

  3. Настоящее задание =. Просто напишите 3 по номеру x.

Итак, в моих глазах ++ применяется перед тем произошло назначение. Я ошибаюсь?

+0

Вы протестировали его? Сделайте простое приложение и попробуйте! –

+2

Почему бы вам просто не проверить его? –

+2

См. Также http://stackoverflow.com/questions/7911776/what-is-x-after-x-x –

ответ

10

... ++ применяется после присвоение произошло.

Хорошо, держись. Это на самом деле запутывает и, возможно, предлагает неправильное поведение.

У вас есть выражение & dagger;:

x = (x++) 

Что происходит (JLS 15.26.1):

  1. Выражение в левой части задания x вычисляется (для получения переменной).
  2. Выражение в правой части задания (x++) оценивается (для получения значения).
  3. Оценка правой части: x после инкремента, а результатом выражения является старое значение x.
  4. Переменной в левой части, x, присваивается значение, полученное оценкой правой части, которое является старым значением x.

Таким образом, приращение происходит до задание.

(Поэтому, как мы знаем, значение xпосле выполнения оператора x = x++; такого же, как значение xперед выполняющим заявлением, которое 3.)

Итак, в моих глазах ++ применяется до задание произошло. Я ошибаюсь?

Вы правы.

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

Только для щеколда это, мы можем также взглянуть на некоторые байткод:

/*       int x = 3;       */ 
iconst_3 // push the constant 3 on to the stack   : temp = 3 
istore_0 // pop the stack and store in local variable 0 : x = temp 
/*       x = x++;        */ 
iload_0 // push local variable 0 on to the stack  : temp = x 
iinc 0 1 // increment local variable 0 by 1    : x = x + 1 
istore_0 // pop the stack and store in local variable 0 : x = temp 

iinc происходит перед istore.

& dagger ;: Скобки не влияют на оценку, они просто для ясности.

+0

Хе-хе, есть ли способ выполнить назначение перед исполнением правой стороны? Я так не думаю ... Это должно быть естественно для всех;) – energizer

+0

@energizer Действительно, мы должны знать значение, прежде чем оно может быть назначено. – Radiodef

-2

++ x называется preincrement, в то время как x ++ называется постинкрестностью.

int x = 3; 
x = ++x; 

Exemple

int x = 5, y = 5; 

System.out.println(++x); // outputs 6 
System.out.println(x); // outputs 6 

System.out.println(y++); // outputs 5 
System.out.println(y); // outputs 6 
+4

вопрос о постфиксном операторе, и верно ли объяснение книги или нет. –

+0

к примеру, он может посвятить книгу правильной. –

+1

Нет, он не может, он спрашивает о порядке выполнения операндов во время назначения, что не является тем, что вы можете проверить на самом языке. –

0

x ++ означает «использовать x, а затем увеличить x».

Вы также можете использовать ++ x, что означает «приращение x, а затем используйте x."

Более легко, однако, вы можете просто сделать

x += 1; 
2

Потянувшись к официальной спецификации:

  1. постфикса раздел ++: https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.14.2
  2. Назначение оператора раздела: https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.26.1

С точки зрения назначения, это простое задание, поэтому мы попали случай 3:

  1. Во-первых, левый операнд вычисляется для получения переменной - x
  2. нет ошибок -> правая операнд - x++
  3. "значение правого операнда преобразуется в тип левой переменной, подвергается преобразованию набора значений (п. 5.1.13) в соответствующий стандартный набор значений (а не набор расширенных значений экспоненты), и результат преобразования сохраняется в переменной «

Таким образом, в шаге 2, оператор постфикс должен разрешится, а затем на шаге 3, х получает снова присваивается свое первоначальное значение:

call: x = x++; 
interframe: LHS is variable 'x' 
interframe: RHS caches return value as 3 
interframe: x is incremented to 4 
interframe: RHS cached value '3' is returned for assignment 
interframe: variable x is assigned value 3 
call result: x = 3 

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