English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Pré++E pós++ Explicação detalhada das operações e código de exemplo

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!

Você também pode gostar