Conceito pós-incremento e pré-incremento?

Eu não entendo o conceito de incremento ou decremento de postfix e prefixo. Alguém pode dar uma explicação melhor?

Todas as quatro respostas até agora estão incorretas , pois afirmam uma ordem específica de events.

Acreditando que a “lenda urbana” levou muitos novatos (e profissionais) a se desviar, a saber, o stream interminável de perguntas sobre o comportamento indefinido em expressões.

Assim.

Para o operador de prefixo C ++ integrado,

++x 

incrementa x e produz como resultado de expressão x como um lvalue, enquanto

 x++ 

incrementa x e produz como expressão resultado o valor original de x .

Em particular, para x++ não há nenhuma ordem de tempo implícita para o incremento e produção do valor original de x . O compilador está livre para emitir código de máquina que produz o valor original de x , por exemplo, pode estar presente em algum registro, e que atrasa o incremento até o final da expressão (próximo ponto de seqüência).

As pessoas que acreditam erroneamente que o incremento precisa vir primeiro, e são muitas, muitas vezes concluem que certas expressões devem ter um efeito bem definido, quando na verdade têm um comportamento indefinido.

 int i, x; i = 2; x = ++i; // now i = 3, x = 3 i = 2; x = i++; // now i = 3, x = 2 

‘Post’ significa after – isto é, o incremento é feito depois que a variável é lida. ‘Pre’ significa antes – então o valor da variável é incrementado primeiro, depois usado na expressão.

Ninguém respondeu a pergunta: Por que esse conceito é confuso?

Como aluno de graduação em Ciência da Computação, demorei um pouco para entender isso por causa da maneira como eu li o código.

O seguinte não está correto!


x = y ++

X é igual a y pós incremento. O que logicamente parece significar que X é igual ao valor de Y depois que a operação de incremento é feita. Poste significado depois .

ou

x = ++ y
X é igual a y pré- incremento. O que logicamente parece significar que X é igual ao valor de Y antes que a operação de incremento seja concluída. Pré significado antes .


A maneira como funciona é na verdade o oposto. Esse conceito é confuso porque a linguagem é enganosa. Neste caso, não podemos usar as palavras para definir o comportamento.
x = ++ y é realmente lido como X é igual ao valor de Y após o incremento.
x = y ++ é realmente lido como X é igual ao valor de Y antes do incremento.

As palavras pré e pós estão invertidas em relação à semântica do inglês . Eles só querem dizer onde o ++ está em relação a Y. Nada mais.

Pessoalmente, se eu tivesse a escolha, eu trocaria os significados de ++ y e y ++. Este é apenas um exemplo de uma linguagem que eu tive que aprender.

Se existe um método para essa loucura eu gostaria de saber em termos simples.

Obrigado pela leitura.

A diferença entre o incremento de postfix , x++ e o incremento de prefixo , ++x , está precisamente em como os dois operadores avaliam seus operandos. O incremento de postfix copia conceitualmente o operando na memory, incrementa o operando original e, finalmente, produz o valor da cópia. Eu acho que isso é melhor ilustrado pela implementação do operador no código:

 int operator ++ (int& n) // postfix increment { int tmp = n; n = n + 1; return tmp; } 

O código acima não será compilado porque você não pode redefinir operadores para tipos primitivos. O compilador também não pode dizer aqui que estamos definindo um operador postfix ao invés de prefixo , mas vamos fingir que este é C ++ correto e válido. Você pode ver que o operador postfix realmente atua em seu operando, mas retorna o valor antigo antes do incremento, portanto, o resultado da expressão x++ é o valor anterior ao incremento. x , no entanto, é incrementado.

O incremento de prefixo também incrementa seu operando, mas gera o valor do operando após o incremento:

 int& operator ++ (int& n) { n = n + 1; return n; } 

Isso significa que a expressão ++x avalia o valor de x após o incremento.

É fácil pensar que a expressão ++x é, portanto, equivalente a assignmnet (x=x+1) . Isto não é precisamente assim, no entanto, porque um incremento é uma operação que pode significar coisas diferentes em diferentes contextos. No caso de um inteiro primitivo simples, certamente ++x é substituível por (x=x+1) . Mas, no caso de um tipo de class, como um iterador de uma linked list, um incremento de prefixo do iterador definitivamente não significa “adicionar um ao object”.

É bem simples. Ambos incrementarão o valor de uma variável. As duas linhas seguintes são iguais:

 x++; ++x; 

A diferença é se você está usando o valor de uma variável sendo incrementada:

 x = y++; x = ++y; 

Aqui, ambas as linhas incrementam o valor de y por um. No entanto, o primeiro designa o valor de y antes do incremento para x, e o segundo atribui o valor de y após o incremento para x.

Portanto, há apenas uma diferença quando o incremento também está sendo usado como uma expressão. Os incrementos pós-incremento depois de retornar o valor. Os incrementos de pré-incremento antes.

 int i = 1; int j = 1; int k = i++; // post increment int l = ++j; // pre increment std::cout << k; // prints 1 std::cout << l; // prints 2 

Post increment implica que o valor i é incrementado depois de ter sido atribuído a k . No entanto, pré-incremento implica que o valor j é incrementado antes de ser atribuído a l .

O mesmo se aplica ao decremento.

A partir do padrão C99 (C ++ deve ser o mesmo, exceto sobrecarga estranha)

6.5.2.4 Operadores de incremento e decremento do postfix

Restrições

1 O operando do operador de incremento ou decremento de postfix deve ter um tipo de ponteiro ou real qualificado ou não qualificado e deve ser um valor modificável.

Semântica

2 O resultado do operador postfix ++ é o valor do operando. Após o resultado ser obtido, o valor do operando é incrementado. (Ou seja, o valor 1 do tipo apropriado é adicionado a ele.) Consulte as discussões sobre operadores aditivos e designação composta para obter informações sobre restrições, tipos e conversões e os efeitos das operações em pointers. O efeito colateral de atualizar o valor armazenado do operando deve ocorrer entre o ponto de seqüência anterior e o seguinte.

3 O postfix – operator é análogo ao operador postfix ++, exceto que o valor do operando é diminuído (ou seja, o valor 1 do tipo apropriado é subtraído dele).

6.5.3.1 Operadores de incremento e decremento de prefixo

Restrições

1 O operando do operador de incremento ou decremento de prefixo deve ter um tipo de ponteiro ou real qualificado ou não qualificado e deve ser um valor modificável.

Semântica

2 O valor do operando do operador prefixo ++ é incrementado. O resultado é o novo valor do operando após o incremento. A expressão ++ E é equivalente a (E + = 1). Veja as discussões sobre operadores aditivos e designação composta para obter informações sobre restrições, tipos, efeitos colaterais e conversões e os efeitos das operações em pointers.

3 O prefixo – operator é análogo ao prefixo ++ operator, exceto que o valor do operando é decrementado.

O pré incremento é antes do valor de incremento ++ por exemplo:

 (++v) or 1 + v 

O incremento pós é após incrementar o valor ++ ex:

 (rmv++) or rmv + 1 

Programa:

 int rmv = 10, vivek = 10; cout << "rmv++ = " << rmv++ << endl; // the value is 10 cout << "++vivek = " << ++vivek; // the value is 11 

Você também deve estar ciente de que o comportamento dos operadores pós-incremento / decremento é diferente em C / C ++ e Java.

Dado

  int a=1; 

em C / C ++ a expressão

  a++ + a++ + a++ 

avalia a 3, enquanto em Java avalia a 6. Adivinha porque …

Este exemplo é ainda mais confuso:

 cout << a++ + a++ + a++ << "<->" << a++ + a++ ; 

imprime 9 <-> 2 !! Isso ocorre porque a expressão acima é equivalente a:

 operator<<( operator<<( operator<<( cout, a++ + a++ ), "<->" ), a++ + a++ + a++ )