O que acontece (atrás das cortinas) quando isso é executado?
int x = 7;
x = x++;
Ou seja, quando uma variável é pós-incrementada e atribuída a si mesma em uma instrução? Eu compilei e executei isso. x
ainda é 7, mesmo depois de toda a declaração . No meu livro, diz que x
é incrementado!
java
operators
post-increment
Michael
fonte
fonte
int x = 7; x = ++x;
é claro que ainda é um código horrível, você não precisa reatribuir.int x = 7; x++;
basta.x += 1
, exceto talvez em loops.for(int x=0; x<7; x++)
Respostas:
x
é incrementado. Mas você está atribuindo o valor antigo dex
volta a si mesmo.x++
incrementax
e retorna seu valor antigo.x =
atribui o valor antigo de volta a si mesmo.Portanto, no final,
x
é atribuído de volta ao seu valor inicial.fonte
x
é incrementado primeiro antes de ser lido nesse caso, então você termina comx + 1
.é equivalente a
fonte
x=x+1
vez dex++
x = x++
, não apenas o pós-incrementox++
.x = ++x;
também seja equivalenteint tmp = x; ++x; x = tmp;
, então por que lógica podemos deduzir que sua resposta está correta (qual é)?x=x++
=MOV x,tmp; INC x; MOV tmp,x
A declaração:
é equivalente a:
Em suma, a declaração não tem efeito.
Os pontos principais:
O valor de uma expressão de incremento / decremento do Postfix é o valor do operando antes que o incremento / decremento ocorra. (No caso de um formulário Prefixo, o valor é o valor do operando após a operação)
o RHS de uma expressão de atribuição é completamente avaliado (incluindo quaisquer incrementos, decrementos e / ou outros efeitos colaterais) antes que o valor seja atribuído ao LHS.
Observe que, diferentemente de C e C ++, a ordem de avaliação de uma expressão em Java é totalmente especificada e não há espaço para variações específicas da plataforma. Os compiladores só podem reordenar as operações se isso não alterar o resultado da execução do código da perspectiva do encadeamento atual. Nesse caso, seria permitido a um compilador otimizar toda a instrução porque pode ser provado que não é uma operação.
Caso ainda não seja óbvio:
Felizmente, verificadores de código como FindBugs e PMD sinalizarão códigos como suspeitos.
fonte
x++
vez dex = x++
.Ele tem um comportamento indefinido em C e, para Java, veja esta resposta . Depende do compilador o que acontece.
fonte
Uma construção como
x = x++;
indica que você provavelmente está entendendo mal o que o++
operador faz:Vamos reescrever isso para fazer a mesma coisa, com base na remoção do
++
operador:Agora, vamos reescrevê-lo para fazer (o que eu acho) que você queria:
A sutileza aqui é que o
++
operador modifica a variávelx
, diferente de uma expressão comox + x
, que seria avaliada para um valor int, mas deixaria ax
própria variável inalterada. Considere uma construção como ofor
loop venerável :Observe o
i++
lá dentro? É o mesmo operador. Poderíamos reescrever essefor
loop assim e ele se comportaria da mesma maneira:Também recomendo não usar o
++
operador em expressões maiores na maioria dos casos. Devido à sutileza de quando ela modifica a variável original antes e depois do incremento (++x
ex++
, respectivamente), é muito fácil introduzir erros sutis que são difíceis de rastrear.fonte
De acordo com o código de bytes obtido dos arquivos de classe,
Ambas as atribuições aumentam x, mas a diferença é o tempo de
when the value is pushed onto the stack
Em
Case1
, o Push ocorre (e depois é atribuído) antes do incremento (significando essencialmente que o incremento não faz nada)Em
Case2
, o incremento ocorre primeiro (tornando-o 8) e depois empurrado para a pilha (e depois atribuído a x)Caso 1:
Código de bytes:
Caso 2:
Código de Byte
fonte
É incrementado após "
x = x++;
". Seria 8 se você fizesse "x = ++x;
".fonte
x = x++
, então ele deve ser 8.O operador Pós-incremento funciona da seguinte maneira:
Então a afirmação
seria avaliado da seguinte forma:
Portanto, x é realmente aumentado, mas como x ++ está atribuindo resultado de volta a x, o valor de x é substituído pelo seu valor anterior.
fonte
O incremento ocorre depois que x é chamado, então x ainda é igual a 7. ++ x seria igual a 8 quando x é chamado
fonte
Quando você atribui novamente o valor,
x
ele ainda é 7. Tentex = ++x
e você terá mais 8fonte
porque x ++ incrementa o valor APÓS atribuí-lo à variável. assim por diante e durante a execução desta linha:
o varialbe x ainda terá o valor original (7), mas usando x novamente em outra linha, como
lhe dará 8.
se você quiser usar um valor incrementado de x na declaração de atribuição, use
Isso aumentará x em 1, ENTÃO atribua esse valor à variável x.
[Edit] em vez de x = x ++, é apenas x ++; o primeiro atribui o valor original de x a si próprio, portanto, na verdade, não faz nada nessa linha.
fonte
O que acontece quando
int x = 7; x = x++;
?ans ->
x++
significa o primeiro valor de uso de x para expressão e depois aumente-o em 1.É o que acontece no seu caso. O valor de x no RHS é copiado para a variável x no LHS e, em seguida, o valor de
x
é aumentado em 1.Da mesma forma
++x
,->
aumente o valor de x primeiro em um e depois use na expressão.Portanto, no seu caso,
x = ++x ; // where x = 7
você receberá um valor de 8.
Para maior clareza, tente descobrir quantas instruções printf executarão o seguinte código
fonte
x
sendo 8, mas é 7 - incremento acontece entre ler e atribuição++x
é pré-incremento->
x é incrementado antes de ser usadox++
é pós-incremento->
x é incrementado após ser usadofonte
Então isso significa:
x++
não é igual ax = x+1
Porque:
e agora parece um pouco estranho:
muito dependente do compilador!
fonte
(x = x + 1, x-1)
em C, onde expressões separadas por vírgula são permitidas.x = x ++;
Este é o operador pós-incremento. Deve ser entendido como "Use o valor do operando e depois aumente o operando".
Se você deseja que o inverso aconteça, ou seja, "Incremente o operando e use o valor do operando", você deve usar o operador de pré-incremento, como mostrado abaixo.
x = ++ x;
Esse operador primeiro incrementa o valor de x em 1 e depois atribui o valor de volta a x.
fonte
Eu acho que essa controvérsia pode ser resolvida sem entrar em código e apenas pensar.
Considere i ++ e ++ i como funções, como Func1 e Func2.
Agora i = 7;
Func1 (i ++) retorna 7, Func2 (++ i) retorna 8 (todo mundo sabe disso). Internamente, ambas as funções aumentam i para 8, mas retornam valores diferentes.
Então i = i ++ chama a função Func1. Dentro da função, eu aumenta para 8, mas após a conclusão, a função retorna 7.
Então, finalmente, 7 é alocado para i. (Então, no final, i = 7)
fonte
Isso ocorre porque você usou um operador pós-incremento. Nesta linha de código a seguir
O que acontece é que você está atribuindo o valor de x para x. x ++ incrementa x depois que o valor de x é atribuído a x. É assim que os operadores pós-incremento funcionam. Eles funcionam após a execução de uma instrução. Portanto, no seu código, x é retornado primeiro depois e depois é incrementado.
Se você fez
A resposta seria 8 porque você usou o operador de pré-incremento. Isso incrementa o valor antes de retornar o valor de x.
fonte