English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Geralmente, o pré-++ adiciona primeiro o valor da variável.1Depois disso, usa-se o valor aumentado1Depois disso, usa-se o valor subsequente para participar das operações; enquanto o pós-++Primeiro, usa-se esse valor para participar das operações, e em seguida, adiciona-se esse valor.1。
Vamos ver o primeiro exemplo:
package test; public class Plus_Test01 { public static void main(String[] args) { int i = 100; i = i++; System.out.println(i); } }
Adivinhe o resultado?
Vamos ver o segundo:
package test; public class Plus_Test02 { public static void main(String[] args) { int k = 100; while (true) { if (k++ > 100) { // System.out.println(k); break; } System.out.println(k); } } }
Adivinhe o resultado?
Na verdade, seja pré-++Ou pós-++Ambos adicionam o valor da variável primeiro.1E só depois continua-se a calcular. A verdadeira diferença entre eles é: pré-++Depois disso, adiciona-se o valor da variável.1Depois disso, usa-se o valor aumentado da variável para realizar operações. A diferença real entre eles é que o pré-++Primeiro, atribui-se a variável a uma variável temporária, e em seguida, adiciona-se o valor da variável.1Depois disso, usa-se essa variável temporária para realizar operações.
Para o seguinte trecho de código (pré-)++):
int i=1;
int j=++i*5;
Na verdade, a segunda frase é equivalente a:
i+=1; //adicionar i1
j=i*5; //Vamos adicionar1O valor subsequente é calculado com ele, e o resultado é:10
Para o seguinte trecho de código (pós-)++):
int i=1;
int j=i++*5;
A segunda frase é equivalente a:
int temp=i; // atribuir i a uma variável temporária
i+=1; //adicionar i1
j=temp*5; //calcular com a variável temporária, este resultado é:5
Para o primeiro exemplo, é equivalente a:
int temp=i;
i+=1;
i=temp; //
Portanto, o resultado deve ser inalterado, ou seja100。
O código assembly do primeiro exemplo é:
public static void main(java.lang.String[]); descrição: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=2, locals=2, args_size=1 : bipush 100 2: istore_1 3: iload_1 4: iinc 1, 1 //o segundo na var local +1 7: istore_1 //salvar na var local 8: getstatic #16 // Campo java/lang/System.out:Ljava/io/PrintStream; 11: iload_1 //o parâmetro carregado é o segundo na pilha, ainda é100 12: invokevirtual #22 // Método java/io/PrintStream.println:(I)V 15: return
Para o segundo exemplo, na verdade não é difícil, o resultado é101,preste atenção ao fluxo, não podemos mais cometer esse erro. (O fluxo é: primeiro comparar temp=i, temp>100, obviamente não é verdadeiro, diminuir i+=1,pular para a linha syso, o que é impresso é101,voltar ao ciclo novamente tem temp=i, temp>100, dessa vez é verdadeiro, então i+=1,sair diretamente do ciclo, não executar a instrução while).
O código assembly do segundo exemplo (apenas选取了main方法):
public static void main(java.lang.String[]); descrição: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=2, locals=2, args_size=1 : bipush 100 //100 empilhar 2: istore_1 //salvar no segundo var local (o primeiro var local é o parâmetro do método) 3: iload_1 //carregar do segundo var local 4: iinc 1, 1 //dar ao var local2número da posição int aumenta1(variável local incrementa, o resultado ainda está na var local, valor na pilha de operandos no topo1não muda) 7: bipush 100 //100 empilhar 9: if_icmple 15 //comparar os dois valores inteiros na pilha de operandos no topo, se o primeiro for menor ou igual ao segundo, então pular para15linha 12: goto 25 //se não pular para25linha (ou pilha de operandos no topo1>pilha de operandos no topo2) 15: getstatic #2 // Campo java/lang/System.out:Ljava/io/PrintStream; 18: iload_1 // //carregar do primeiro var local 19: invokevirtual #3 // Método java/io/PrintStream.println:(I)V //chamar este método 22: goto 3 //voltar para3,voltar ao ciclo 25: return //Sair
Terceiro exemplo:
package test; public class Plus_Test03 { static int proPlus() { int i = 55; int j = ++i; return j; //56 } static int postPlus() { int i = 55; int j = i++; return j; //55 } public static void main(String[] args) { System.out.println(proPlus());//56 System.out.println(postPlus());//55 } }
A汇编 do terceiro exemplo:
static int proPlus(); descriptor: ()I flags: ACC_STATIC Code: stack=1, locals=2, args_size=0 : bipush 55 //55: push 2: istore_0 //Armazene no primeiro local var o armazenamento do topo do tipo int da pilha 3: iinc 0, 1 //O primeiro local var adiciona1 6: iload_0 //Carregue do local var 7: istore_1 //Salve no segundo local var 8: iload_1 //O topo da pilha é o segundo local var 9: ireturnstatic int postPlus(); descriptor: ()I flags: ACC_STATIC Code: stack=1, locals=2, args_size=0 : bipush 55 2: istore_0 3: iload_0 //: load 4: iinc 0, 1 //O primeiro local var adiciona1 7: istore_1 8: iload_1 9: ireturn
Portanto, pré++ E pós++A diferença está na parte azul (//O primeiro local var adiciona1A parte do parêntese), essas duas partes são inversas. Para pré, adiciona o número do local var1Em seguida, carregue para a pilha, e pós é primeiro carregar do local var para a pilha, em seguida, adicionar o local var1equivalente a deixar uma cópia de segurança.
Conclusão:
Primeiro, pré e pós++Ambos primeiro adicionam o valor da variável1ao invés de pré++Primeiro, some1Em seguida, calcule, e pós++Primeiro, calcule, em seguida, some pós1。
Dois. Do ponto de vista do programa, pós++Primeiro, atribua o valor da variável a uma variável temporária, em seguida, some o valor da variável.1, em seguida, usar essa variável temporária para participar da operação.
Três. Do ponto de vista das instruções, pós++Antes de executar a instrução de aumento (iinc), o valor da variável é empilhado no pilha, e o valor empilhado anteriormente é usado após a execução da instrução de aumento.
Espero que com este artigo, você possa entender completamente o pré++E pós++A diferença de operação, obrigado pela apoio deste site!