Acredita-se geralmente que a pré-posição ++ primeiro adicione o valor da variável a 1 e depois use o valor após adicionar 1 para participar da operação; Enquanto o pós-posição ++ primeiro usa o valor para participar da operação e, em seguida, adiciona o valor a 1.
Vamos dar uma olhada no primeiro exemplo:
teste de pacote; classe pública Plus_test01 {public static void main (string [] args) {int i = 100; i = i ++; System.out.println (i); }}Adivinha qual é o resultado?
Vejamos o segundo:
teste de pacote; public class Plus_test02 {public static void main (string [] args) {int k = 100; while (true) {if (k ++> 100) {// System.out.println (k); quebrar; } System.out.println (k); }}}Adivinha qual é o resultado?
De fato, se é pré-++ ou post-++, o valor da variável é aumentado primeiro em 1 antes de continuar a calcular. A diferença real entre os dois é: o pré-++ adiciona o valor da variável por 1 e usa o valor agregado para executar cálculos, enquanto o post-++ atribui primeiro a variável a uma variável temporária e depois adiciona 1 ao valor da variável e depois usa essa variável temporária para executar cálculos.
Para o seguinte snippet de código (prefixo ++):
int i = 1;
int j = ++ i*5;
De fato, a segunda frase é equivalente a:
i+= 1; // Adicione i a 1
j = i*5; // Calcule o valor após adicionar 1 com ele, o resultado é: 10
E para o seguinte snippet de código (post-++):
int i = 1;
int j = i ++*5;
A segunda frase é equivalente a:
int temp = i; // atribui i a uma variável temporária
i+= 1; // Adicione i a 1
j = temp*5; // Calcule a variável temporária com ele, o resultado é: 5
Para o primeiro exemplo, é equivalente a:
int temp = i;
i+= 1;
i = temp; //
Portanto, o resultado deve permanecer inalterado, ou seja, 100.
O código de montagem para o primeiro exemplo é:
public static void main (java.lang.string []); Descritor: ([ljava/lang/string;) v sinalizadores: acc_public, acc_static Code: Stack = 2, habitantes locais = 2, args_size = 1 0: bipush 100 2: iStore_1 3: iload_1 4: iinc 1, 1 // o segundo no local mais 1 7: java/lang/system.out: ljava/io/printStream; 11: ILOAD_1 // O parâmetro carregado é o segundo na pilha, ou seja, ainda é 100 12: InvokeVirtual #22 // Método java/io/printStream.println: (i) v 15: retornar
Para o segundo exemplo, na verdade não é difícil, mas o resultado é 101. Preste atenção ao processo e você não pode cometer esses erros no futuro. (O processo é: primeiro compare temp = i, temp> 100, obviamente não é verdadeiro. Pule i+= 1 na frase syso, é claro, imprima 101, loop novamente, e também há temp = i, temp> 100, desta vez não será verdadeiro e depois i+= 1, salta diretamente do loop e a declaração e a declaração de quando não será executada).
Compilação do segundo exemplo (apenas o método principal é selecionado):
public static void main (java.lang.string []); Descritor: ([ljava/lang/string;) v sinalizadores: acc_public, acc_static Code: Stack = 2, habitantes locais = 2, args_size = 1 0: bipush 100 // 100 push pilha 2: istore_1 // salvar no segundo var (o primeiro local local 4 o parâmetro do método) 3: Iload the position 2 of local var (the local variable increases, the result is still in the local var, the top 1 of the operand stack will not change) 7: bipush 100 //100 push stack 9: if_icmple 15 //Compare the two int integer values at the top of the operand stack, if the first one is less than or equal to the second one, then jump to line 15 12: goto 25 // Otherwise jump to line 25 (i.e., operand stack top 1> pilha de operando top 2) 15: getstatic #2 // campo java/lang/system.out: ljava/io/printStream; 18: ILOAD_1 // // Carregar do primeiro Var 19 local: InvokeVirtual #3 // Método java/io/printStream.println: (i) v // Ligue para este método 22: Goto 3 // Voltar para 3 novamente, loop novamente 25: retornar // saída
O terceiro exemplo:
teste de pacote; public class Plus_test03 {static int proplus () {int i = 55; int j = ++ i; retornar j; // 56} static int postplus () {int i = 55; int j = i ++; retornar j; // 55} public static void main (string [] args) {System.out.println (proplus ()); // 56 system.out.println (postplus ()); // 55}}Compilação do terceiro exemplo:
estático int proplus (); Descritor: () I Bandeiras: Acc_static Code: Stack = 1, Locais = 2, Args_size = 0 0: Bipush 55 // 55 Stack 2: IStore_0 // Armazene a parte superior da pilha int para o primeiro Var 3: iinc 0, 1 // o primeiro var local mais 1 6: iload_0 // LOAD // Local de Local: 1 // O primeiro var para o Var mais 1: iloAD_0 // iload_1 // A parte superior da pilha é o segundo Var 9: IReturnStatic int pós -plus (); Descritor: () I Sinalizadores: Acc_static Code: Stack = 1, Locais = 2, args_size = 0 0: Bipush 55 2: IStore_0 3: ILOAD_0 // Carregue para empilhamento 4: iinc 0, 1 // o primeiro local Var mais 1 7: IStore_1 8: iload_1 9
Pode -se observar que a diferença entre a frente ++ e a traseira ++ é a parte azul acima (// o primeiro Var Local Plus 1), que é o oposto. Para o antecessor, o número no VAR local será adicionado 1 e depois carregado na pilha, enquanto o último será carregado do VAR local da pilha para a pilha e, em seguida, o Var local será adicionado 1, o que equivale a deixar um backup.
para concluir:
um. A pré-posição e a pós-posição ++ adicionam 1 ao valor da variável primeiro, em vez de adicionar 1 à pré-posição ++ e depois calcular, enquanto o pós-posição ++ primeiro e depois calcula.
dois. De um modo programaticamente, o post-++ atribui primeiro a variável a uma variável temporária e adiciona o valor da variável por 1 e depois usa a variável temporária para participar da operação.
três. Do ponto de vista da instrução, o valor da variável é empurrado para a pilha antes de executar a instrução de valor agregada (iinc). Depois de executar a instrução de valor agregado, o valor empurrado para a pilha é usado.
Espero que, durante este artigo, compreendi minuciosamente a diferença entre as operações de pré-posição ++ e pós-posição ++. Obrigado pelo seu apoio a este site!