В коде я вижу часто
x++
в loops, но когда-нибудь нахожусь++x
.
, Если ты имеешь в виду конструкции этого типа:
public static void main(String[] args) {
for (int i = 0; i < 10; ++i) {
System.out.println(i);
}
for (int i = 0; i < 10; i++) {
System.out.println(i);
}
}
... тогда не есть различие. Если мы видим bytecode :
public static void main(java.lang.String[]);
Code:
0: iconst_0
1: istore_1
2: iload_1
3: bipush 10
5: if_icmpge 21
8: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
11: iload_1
12: invokevirtual #3 // Method java/io/PrintStream.println:(I)V
15: iinc 1, 1
18: goto 2
21: iconst_0
22: istore_1
23: iload_1
24: bipush 10
26: if_icmpge 42
29: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
32: iload_1
33: invokevirtual #3 // Method java/io/PrintStream.println:(I)V
36: iinc 1, 1
39: goto 23
42: return
В обоих случаях, справедливый человек despuГ©s призывания println
(invokevirtual #3
), увеличивает переменную 1 (в cГіdigo i
для обоих случаев) в 1. VГ©ase iinc 1, 1
перед goto
.
Тем не менее, если ты имеешь в виду что-то как это:
public static void main(String[] args) {
for (int i = 0; i < 10;) {
System.out.println(i++);
}
for (int i = 0; i < 10;) {
System.out.println(++i);
}
}
... тогда sГ - есть различие. Проверяя bytecode :
public static void main(java.lang.String[]);
Code:
0: iconst_0
1: istore_1
2: iload_1
3: bipush 10
5: if_icmpge 21
8: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
11: iload_1
12: iinc 1, 1
15: invokevirtual #3 // Method java/io/PrintStream.println:(I)V
18: goto 2
21: iconst_0
22: istore_1
23: iload_1
24: bipush 10
26: if_icmpge 42
29: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
32: iinc 1, 1
35: iload_1
36: invokevirtual #3 // Method java/io/PrintStream.println:(I)V
39: goto 23
42: return
В первом случае, сначала загружает стоимость переменной 1 (i
), чтобы быть использованным в println
. VГ©ase iload_1
. DespuГ©s увеличивается эта переменная в 1. VГ©ase iinc 1, 1
.
Во втором случае, сначала увеличивает стоимость переменной 1 (i
) в 1, VГ©ase iinc 1, 1
. Потом загружает стоимость переменной 1 (i
), чтобы быть использованным в println
. VГ©ase iload_1
.
x++
, Стоимость выражения - стоимость переменной, нежели новая стоимость хранилась.
Пример:
int x = 1;
System.out.println(x++); // imprime 1.
System.out.println(x); // imprime 2.
++x
, Стоимость выражения - стоимость переменной после, что новая стоимость хранится.
Пример:
int x = 1;
System.out.println(++x); // imprime 2.
System.out.println(x); // imprime 2.
Сходный для x--
и --x
Примеры:
int x = 1;
System.out.println(x--); // imprime 1.
System.out.println(x); // imprime 0.
int x = 1;
System.out.println(--x); // imprime 0.
System.out.println(x); // imprime 0.
Больше информации:
Различие не, в котором увеличение работало раньше, или оценив выражение а в стоимости возврата двух выражений
Согласно официальной спецификации Java в секции: 15.14.2. Postfix Инкремент Оператор ++ и 15.15.1. Prefix Инкремент Оператор ++
15.14.2. Postfix Инкремент Оператор ++
... The оцените of the postfix increment expression is the оцените of the переменную before the new оцените is stored.
Перевод
15.14.2. Оператор Постустановленного Увеличения ++
Стоимость выражения постустановленного увеличения - стоимость переменной, нежели новая стоимость хранилась.
Также
15.15.1. Prefix Инкремент Оператор ++
The оцените of the prefix increment expression is the оцените of the переменную after the new оцените is stored.
Перевод
15.15.1. Оператор Увеличения Предопределил ++
Стоимость выражения увеличения префикса - стоимость переменной после, что новая стоимость хранится.
Оба увеличивают переменную x
в 1. Различие - что выражение ++x
возвращает стоимость увеличенной переменной взамен выражение x++
возврати первоначальную стоимость переменной перед тем, как быть увеличенной.
А именно:
int x = 5;
System.out.println(++x); // Imprime 6, x vale 6: El resultado de la expresión ++x es 6 y se imprime 6
System.out.println(x); // Imprime 6, x vale 6: x ya se incrementó por lo que devuelve 6
В то время как:
int x = 5;
System.out.println(x++); // Imprime 5, x vale 6. La variable x ya es 6 pero el resultado de la expresión es 5 por lo que se imprime 5
System.out.println(x); // Imprime 6, x vale 6: x ya se incrementó por lo que devuelve 6
System.out.println()
и потом eval и # 250; и expresi и # 243; n, что является Вашим аргументом, когда в действительности eval и # 250; сначала x++
и потом Ваш результат перемещен System.out.println()
, оба префикс и я постзакрепляю они увеличивают переменную как результат оценивания expresi и # 243; n
– Carlos Muñoz
05.12.2015, 01:51
Я знаю, что вопрос находится taggeada в Java, и не знаю осуществление в этом языке (хотя я предполагаю, что он будет сходным), но в C#, хотя нормальное и интуитивное а именно, что "один возвращает стоимость перед тем, как увеличивать, и другой после", и это более или менее дает основное значение... реальность состоит в том, что осуществление не является таким, и у него есть очень конкретная последовательность событий.
Это не проблема, если мы это используем только: x++;
он не приносит никакой проблемы и простое объяснение действительное..., но если мы проникаем в мультитрэды, и длинные операции с различным предшествованием операторов, вещь меняется.
Как я говорю, не знаю, как это делает Java, но в C#, последовательность каждой команды верно определена (и я представляю, что в Java он будет сходным):
Для типа префикса (++x
), последовательность:
x
чтобы производить переменнуюДля типа суффикс (x++
), последовательность:
x
чтобы производить переменнуюСледовательно, последовательность событий происходит в обоих случаях в том же порядке, и не меняет даже оценки ни увеличение переменной, единственного, которую он меняет, - стоимость, которая возвращается. Только есть различие в шаге 5.
В C# используя расширение методов, это очень легкое для того, чтобы быть протестированным... в Java мне это не таково ясно (только у меня есть основные понятия Java).
Прощение из-за того, что я ответил используя C#, будучи taggeada вопрос как Java, но как уже я говорю, подозреваю, что осуществление должно быть сходным, если не равный.
Оба увеличивают стоимость переменной в 1
. Если ты используешь их в линии, где это было единственное выражение, нет никакого различия, но если ты выполняешь их вместе с другими, есть важное изменение.
++ x это делает до того, как была оценена она expresiГіn. Также называются PREINCREMENTO
Пример:
int x = 5;
System.out.println(++x); // escribira 6 porque ejecutará x + 1 ANTES de printar
System.out.println(x); // volverá a escribir 6!!!!
x ++ это делает позже в тот, что expresiГіn она была оценена. TambiГ©n называются POSTINCREMENTO
Пример:
int x = 5;
System.out.println(x++); // escribirá 5 porque ejecutará x + 1 DESPUÉS de printar
System.out.println(x); // escribirá 6
Восток тип выражений также очень обычный, сделав ассигнования array, когда ты реализуешь цикл без счетчика (например for-each) или наполняя несколько свойств того же объекта избавляя так от линии кода и зарабатывая читабельность.
arrayALlenar[i++] = elemento;
вместо
arrayALlenar[i] = elemento;
i++;
System.out.println(x++); // escribirá 5 porque ejecutará x + 1 DESPUÉS de printar .
, Хотя печатать и # 225; 5, explicaci и # 243; n она неправильная. Сначала eval и # 250; в аргумент x++
и потом работает м и # 233; совсем println
. То, за чем оно действительно последует, состоит в том, что переменная увеличивается, но , оказанный из expresi и # 243; n быть и # 225; стоимость, которую имей, и # 237; в оригинально а следовательно он возвращает 5
– Carlos Muñoz
03.12.2015, 19:12
Оба делают то же самое кроме того, что тот постувеличения оценивается в стоимость переменной ДО ТОГО, КАК хранилась увеличенная стоимость и стоимость предувеличения он оценивается в стоимость переменной ПОСЛЕ ТОГО, КАК хранилась увеличенная стоимость.
pre и post увеличение они определяются в Спецификации Языка Java (JLS) в двух разделах тех, которых я воспроизвожу переведенные части, которые значительные для этого вопроса (моя эмфаза):
15.14.2:Operador Постустановленного Увеличения ++
(. опущенный.)
Во время выполнения, если оценка выражения завершается круто, тогда выражение постустановленного увеличения завершает круто for тот же разум и нет увеличения. В противоположном случае, стоимости 1 добавляется к стоимости переменной и сумма хранится в переменной. (... опущенный...) Стоимость выражения постустановленного увеличения - стоимость переменной до того, как хранилась новая стоимость.
(. опущенный.)
15.15.1. Оператор Увеличения Предопределил ++
(. опущенный.)
Во время выполнения, если оценка выражения завершается круто, тогда выражение уменьшения префикса завершает круто for тот же разум и нет увеличения. В противоположном случае, стоимости 1 добавляется к стоимости переменной и сумма хранится в переменной. (... опущенный...) Стоимость выражения постустановленного увеличения - стоимость переменной после того, как новая стоимость хранилась.
(. опущенный.)
Наблюдайтесь, что он совсем равен, за исключением стоимости, с которой оценивается выражение, которое является тем, у которого была переменная до того, как хранилась новая стоимость, увеличенная для постустановленного увеличения, и - стоимость, у которой есть переменная после того, как был увеличен для увеличения префикс.
У всего этого нет никакой важности в коде как следующий:
for ( int n=1; n<10; ++n)
for ( int n=1; n<10; n++)
В этом коде, для той же стоимости n
, выражения ++n
и n++
они оцениваются в отличную стоимость, но это неуместное, так как эта стоимость не использована и единственное, у чего есть значительный эффект, - тот факт, что переменная увеличилась в 1, который происходит в обоих случаях. Оба цикла выполнят то же число повторений.
Но да это важно в коде как следующий:
int a; int b;
a = 3;
b = a++;
System.out.println( "a="+a + " b=" + b);
a = 3;
b = ++a;
System.out.println( "a="+a + " b=" + b);
Где вывод:
a=4 b=3
a=4 b=4
В выражении b = a++
оценивается переменная a
(что стоит 3), добавляет 1 к этой стоимости и результат суммы (4) хранится в переменной в. Результат выражения a++
это стоимость, у которой есть переменная a
до того, как хранилась новая стоимость (которой было 3), с которым результат выражения a++
его 3. И это, 3, - то, что хранится в b
.
В выражении b = ++a
оценивается переменная a
(что стоит 3), добавляет 1 к этой стоимости и результат суммы (4) хранится в переменной a
. Результат выражения ++a
это стоимость, у которой есть переменная a
после того, как хранилась новая стоимость (которой 4), с которым результат выражения ++a
его 4. И это, 4, - то, что хранится в b
.
Продолжая estríctamente этот способ оценивать увеличение pre и постустановленный мы можем оценивать corréctamente любое выражение, в которое они были бы введены. Например:
int a; int b;
a = 3;
b = ++a + a++;
System.out.println( "a="+a + " b=" + b);
a = 3;
b = a++ + a++;
System.out.println( "a="+a + " b=" + b);
В первом выражении b
закончи тем, что стой 8, потому что первый ++a
оценивается 4 (стоимость, когда хранили увеличение) и для, когда работает второй a++
переменная a
уже он содержит 4, увеличивается в 5 но стоимость выражения a++
это тот переменной перед тем, как увеличиваться, с которым оценивается 4. И 4+4=8.
Во втором выражении b
закончи тем, что стой 7, потому что первый a++
оценивается 3 (стоимость перед тем, как хранить увеличение) и для, когда работает второй a++
переменная a
уже он содержит 4, увеличивается в 5 но стоимость выражения a++
это тот переменной перед тем, как увеличиваться, с которым оценивается 4. И 3+4=7.
Хотя мы поймем perféctamente, как функционируют операторы pre и post я увеличиваю использовать их в выражениях, которые не были бы тривиальными, только будешь служить для того, чтобы запутать. В тебя, в твоих сотрудников, в твоего координатора, в которого он проверяет код, в который он должен заниматься кодом 5 лет спустя, когда тот, кто написал это коту уже давно, что ушел из предприятия...