Há alguns operadores em C++ que são equivalentes as seguintes expressões (que são bastante comuns em programas):
k = k + 1; j = j - 1;
Estes operadores adicionais, que são ++ e - -, podem ser usados para encurtar as operações acima:
k++; j--;
Estes operadores também podem ser colocados depois do nome da variável:
++k; --j;
O fato do operador de incremento ser colocado antes ou depois da variável não altera o efeito da operação - o valor da variável é incrementada ou decrementada de um. A diferença entre os dois casos é QUANDO a variável é incrementada. Na expressão k++, o valor de k é primeiro usado e então é incrementada - isto é chamado pós-incremento. Na expressão ++k, k é incrementado primeiro, e então o valor (o novo valor) de k é usado - isso é chamado pré-incremento.
A diferença é ilustrada nos seguintes exemplos:
int main() { int k = 5; cout << "k1 = " << k << endl; cout << "k2 = " << k++ << endl; cout << "k3 = " << k << endl; }
O programa acima (que usa pós-incremento) imprimirá o seguinte:
k1 = 5
k2 = 5
k3 = 6
A segunda linha impressa com o valor de k é 5 porque o valor de k++ era 5, e k é 6 depois da impressão.
Para o programa:
int main() { int k = 5; cout << "k1 = " << k << endl; cout << "k2 = " << ++k << endl; cout << "k3 = " << k << endl; }
O programa, que usa pré-incremento, terá a seguinte saída:
k1 = 5
k2 = 6
k3 = 6
A segunda linha impressa é 6 porque o valor de ++k é 6.
Os operadores de atribuição não podem ser usados com expressões aritméticas. Por exemplo, as expressões
(ack + 2)++; (nope + 3) += 5;
resultarão em erros de compilação.
Finalmente, quando usar o operador de incremento em um cout, tome cuidado para não fazer o seguinte:
cout << ++uhoh << uhoh * 2 << endl;
Embora isso seja perfeitamente legal em C++ , os resultados não são garantidados que sejam consistentes. A razão para isso é que não há garantia que os argumentos do cout sejam avaliados em uma determinada ordem. O resultado do cout será diferente dependendo se ++uhoh é avaliado primeiro ou depois de uhoh * 2.
A solução para este problema é escrever o seguinte:
++uhoh; cout << uhoh << uhoh * 2 << endl;
Já que incremento e decremento são formas de atribuição, o operando deve ser um lvalue. O valor de uma expressão de incremento ou decremento depende se o operador é usado na notação PRé ou PóS fixada (x++, ++x, x--, --x). Se for pré-fixada, o valor da expressão é o novo valor após o incremento ou decremento. Se for pós-fixada, o valor da expressão é o valor antigo (antes do incremento ou decremento). Por exemplo no caso de incremento, a expressão:
x++ tem o valor de x
++x tem o valor de x + 1
Note que não importando a notação usada, o valor de x (o conteúdo do endereço de memória associada a x) será x + 1. A diferença está no valor das expressões x++ e ++x, não no valor de x (em ambos os casos o valor de x será incrementada de um).
Às vezes, problemas podem acontecer devido o fato que C++ não especifica a ordem de avaliação dos operadores em uma operação binária. Em outras palavras, em expressões como a + b ou a < b, não há maneira de saber se o valor de a será avaliado antes ou depois de b (pense em a e b como sendo qualquer expressão, não somente variáveis.) Qual deles será avaliado primeiro é particular de cada compilador, e diferentes compiladores em máquinas diferentes podem ter resultados diferentes. Portanto, se a avaliação de um dos operadores pode alterar o valor do outro, o resultado pode ser diferente dependendo da ordem de avaliação. Portanto, em expressões do tipo x + x++, o valor pode diferir dependendo do compilador utilizado. Isto porque não sabemos quando exatamente o incremento de x ocorre. Outros maus exemplos: y = x + x-- e x = x++. De forma geral, para evitar este problema, não utilize senteças como estas.
Como podemos ver, os operadores de incremento/decremento, e os operadores de atribuição aritmética vistos até aqui funcionam de forma similar ao comando de atribuição. O lado esquerdo da expressão de atribuição aritmética e o operando de incremento/decremento devem ser um lvalue. O valor da expressão da é igual ao valor da sentença de atribuição correspondente. Por exemplo:
x += 3 é igual a x = x + 3 e tem valor x + 3
x *= y + 1 é igual a x = x * (y + 1) e tem valor x * (y + 1)
y = i++ é igual a y = i, i = i + 1; e tem valor i
y = ++i é igual a i = i + 1, y = i; e tem valor i + 1
O que é impresso pelos dois programas abaixo?
#include <iostream> using namespace std; int main() { int n1, n2, n3; cout << "Entre com um numero inteiro: "; cin >> n1; n1 += n1 * 10; n2 = n1 / 5; n3 = n2 % 5 * 7; n2 *= n3-- % 4; cout << n2 << " " << n3 << " " << (n2 != n3 + 21) << endl; }
A tabela de precedência abaixo mostra a posição dos operadores vistos aqui, incluindo a atribuição aritmética e decremento/incremento.
Operador | Associatividade |
() [] -> . |
esquerda para direita |
! - ++ -- * \& |
direita para esquerda |
* / % |
esquerda para direita |
+ - |
esquerda para direita |
< <= > >= |
esquerda para direita |
== != |
esquerda para direita |
&& |
esquerda para direita |
|| |
esquerda para direita |
= += -= *= /= %= |
direita para esquerda |
, |
esquerda para direita |