Este é um assunto básico de programação mas que costuma gerar dores de cabeça em quem está começando a estudar, especialmente para aqueles que se habituaram a colocar o operador ‘++ ou –‘ depois de suas variáveis.
Entre os programadores é comum se dizer que “existem dois tipos de desenvolvedores, aqueles que abrem as chaves ({) na mesma linha e aqueles que o fazem na linha seguinte”. Acredito que o mesmo vale para o operador de incremento/decremento, quando começamos a estudar é natural se desenvolver certos vícios quanto a sintaxe que na maioria das vezes não geram danos, entretanto o mesmo não vale para o operador de incremento ou decremento.
1. O Operador de Incremento / Decremento
Uma das tarefas mais comuns em programação é realizar o incremento ou decremento de variáveis principalmente quando nos deparamos com alguma estrutura de repetição e como tal utilizamos o seguinte código:
indice = indice + 1 // Para Incremento
indice = indice - 1 // Para Decremento
Mas como em qualquer área da programação, sempre que surgem tarefas repetitivas em pouco tempo será desenvolvido algum recurso ou ferramenta buscando facilitar e diminuir o número de caracteres que devem ser inseridos aumentando assim a velocidade de codificação.
Tal característica também vale para quando queremos incrementar ou decrementar uma variável. Por ser algo extremamente comum basta usarmos o operador ‘++ ou –‘ antes ou depois da variável a qual se deseja modificar o valor.
++ indice ou indice ++ // Para Incremento
-- indice ou indice -- // Para Decremento
Em resumo o operador ‘++ ou –‘ nada mais é do que duas operações descritas com um único simbolo, isto é, quando incrementamos ou decrementamos uma variável com esses operadores o que estamos fazendo é somando ou subtraindo uma unidade da variável e então salvando o resultado na mesma variável.
2. Pré e Pós Incremento / Decremento
Na seção anterior você deve ter percebido que existem duas formas de se realizar o incremento ou decremento de variáveis através de operadores matemáticos sendo que na maioria das situações a utilização de uma ou de outra forma não fará diferença no código. Entretanto por mais que ao final a variável em questão tenha seu valor atualizado em uma unidade o processo como isto ocorre é totalmente diferente e portanto existem situações na qual a lógica do seu algoritmo será comprometida.
De forma simples o pré incremento ocorre quando o simbolo ‘++ ou –‘ é colocado antes da variável e dessa forma primeiro a variável terá seu valor atualizado para só então ser utilizado pelo algoritmo. Em contrapartida o pós incremento ocorre quando o simbolo ‘++ ou –‘ é colocado após a variável e assim o valor da mesma será primeiramente utilizado da forma como estiver para só então ser atualizado.
Operador Matemático | Significado |
++x | y = x + 1: Soma uma unidade à x e então atribui o resultado da operação em y |
x++ | y = x: Atribui o valor de x à y e só depois soma uma unidade de x |
– -x | y = x – 1: Subtrai uma unidade de x e então atribui o resultado da operação em y |
x- – | y = x: Atribui o valor de x à y e só depois subtrai uma unidade de x |
3. Exemplos
A melhor forma de se entender consiste na utilização de exemplos, logo a seguir vou descrever algumas situações nas quais costumo ver esse problema ocorrer com frequência.
Os exemplos estão descritos apenas em C e Java pois em Python não existe a implementação dos operadores ‘++ e –‘, ao invés disso utilize operador ‘+= ou -=’. Vale notar que esse é um dos motivos pelos quais esse tipo de problema não existe em Python.
3.1. Imprimindo Variáveis
C/C++
#include <stdio.h>
int main(void) {
int indice = 1;
//Pós Incremento
printf("Indice: %d\n", indice++); // Imprime indice antes de somar 1
// Soma 1 a variável indice
printf("Indice: %d\n", indice); // Imprime indice agora com o valor atualizado
printf("Indice: %d\n", indice--); // Imprime indice antes de subtrair 1
// Subtrai 1 da variável indice
printf("Indice: %d\n", indice); // Imprime indice agora com o
//Pré Incremento
printf("Indice: %d\n", ++indice); // Soma 1 e depois imprime o valor
printf("Indice: %d\n", indice); // Imprime indice
printf("Indice: %d\n", --indice); // Subtrai 1 e depois imprime o valor
printf("Indice: %d\n", indice); // Imprime indice
return 0;
}
Java
class Main {
public static void main(String[] args) {
int indice = 1;
//Pós Incremento
System.out.printf("Indice: %d\n", indice++); // Imprime indice antes de somar 1
// Soma 1 a variável indice
System.out.printf("Indice: %d\n", indice); // Imprime indice agora com o valor atualizado
System.out.printf("Indice: %d\n", indice--); // Imprime indice antes de subtrair 1
// Subtrai 1 da variável indice
System.out.printf("Indice: %d\n", indice); // Imprime indice agora com o
//Pré Incremento
System.out.printf("Indice: %d\n", ++indice); // Soma 1 e depois imprime o valor
System.out.printf("Indice: %d\n", indice); // Imprime indice
System.out.printf("Indice: %d\n", --indice); // Subtrai 1 e depois imprime o valor
System.out.printf("Indice: %d\n", indice); // Imprime indice
}
}
3.2. Armazenando Valores
C/C++
#include <stdio.h>
int main(void) {
int valorA = 0;
int valorB = 0;
//Pós Incremento
valorA = valorB++;
printf("Valor A: %d\n", valorA); //Imprime "0"
printf("Valor B: %d\n", valorB); //Imprime "1"
valorA = valorB--;
printf("Valor A: %d\n", valorA); //Imprime "1"
printf("Valor B: %d\n", valorB); //Imprime "0"
//Pré Incremento
valorA = ++valorB;
printf("Valor A: %d\n", valorA); //Imprime "1"
printf("Valor B: %d\n", valorB); //Imprime "1"
valorA = --valorB;
printf("Valor A: %d\n", valorA); //Imprime "0"
printf("Valor B: %d\n", valorB); //Imprime "0"
}
Java
class Main {
public static void main(String[] args) {
int valorA = 0;
int valorB = 0;
//Pós Incremento
valorA = valorB++;
System.out.printf("Valor A: %d\n", valorA); //Imprime "0"
System.out.printf("Valor B: %d\n", valorB); //Imprime "1"
valorA = valorB--;
System.out.printf("Valor A: %d\n", valorA); //Imprime "1"
System.out.printf("Valor B: %d\n", valorB); //Imprime "0"
//Pré Incremento
valorA = ++valorB;
System.out.printf("Valor A: %d\n", valorA); //Imprime "1"
System.out.printf("Valor B: %d\n", valorB); //Imprime "1"
valorA = --valorB;
System.out.printf("Valor A: %d\n", valorA); //Imprime "0"
System.out.printf("Valor B: %d\n", valorB); //Imprime "0"
}
}
3.3. Indexando Vetores
C/C++
#include <stdio.h>
int main(void) {
int vetor[] = {0,1,2,3,4,5,6};
int indice = 0;
//Pós Incremento
printf("Valor: %d\n", vetor[indice++]); //Imprime indice sem somar 1
// Soma 1 à indice
printf("Valor: %d\n", vetor[indice]); //Imprime indice
printf("Valor: %d\n", vetor[indice--]); //Imprime indice sem subtrair 1
// Subtrai 1 de indice
printf("Valor: %d\n", vetor[indice]); //Imprime indice
//Pré Incremento
printf("Valor: %d\n", vetor[++indice]); //Soma 1 à indice e então imprime
printf("Valor: %d\n", vetor[indice]); //Imprime indice
printf("Valor: %d\n", vetor[--indice]); //Subtrai 1 de indice e então imprime
printf("Valor: %d\n", vetor[indice]); //Imprime indice
return 0;
}
Java
class Main {
public static void main(String[] args) {
int vetor[] = {0,1,2,3,4,5,6};
int indice = 0;
//Pós Incremento
System.out.printf("Valor: %d\n", vetor[indice++]); //Imprime indice sem somar 1
// Soma 1 à indice
System.out.printf("Valor: %d\n", vetor[indice]); //Imprime indice
System.out.printf("Valor: %d\n", vetor[indice--]); //Imprime indice sem subtrair 1
// Subtrai 1 de indice
System.out.printf("Valor: %d\n", vetor[indice]); //Imprime indice
//Pré Incremento
System.out.printf("Valor: %d\n", vetor[++indice]); //Soma 1 à indice e então imprime
System.out.printf("Valor: %d\n", vetor[indice]); //Imprime indice
System.out.printf("Valor: %d\n", vetor[--indice]); //Subtrai 1 de indice e então imprime
System.out.printf("Valor: %d\n", vetor[indice]); //Imprime indice
}
}
3.4. Indexando Matrizes
C/C++
#include <stdio.h>
int main(void) {
int matriz[3][3] = {{0,1,2},
{3,4,5},
{6,7,8}
};
int indice = 0;
//Pós Incremento
printf("Valor: %d\n", matriz[0][indice++]); //Imprime [0][indice] sem somar 1
// Soma 1 à indice
printf("Valor: %d\n", matriz[0][indice]); //Imprime [0][indice]
printf("Valor: %d\n", matriz[0][indice--]); //Imprime [0][indice] sem subtrair 1
// Subtrai 1 de indice
printf("Valor: %d\n", matriz[0][indice]); //Imprime [0][indice]
//Pré Incremento
printf("Valor: %d\n", matriz[0][++indice]); //Soma 1 à indice e então imprime [0][indice]
printf("Valor: %d\n", matriz[0][indice]); //Imprime [0][indice]
printf("Valor: %d\n", matriz[0][--indice]); //Subtrai 1 de indice e então imprime [0][indice]
printf("Valor: %d\n", matriz[0][indice]); //Imprime [0][indice]
}
Java
class Main {
public static void main(String[] args) {
int [][]matriz = {{0,1,2},
{3,4,5},
{6,7,8}
};
int indice = 0;
//Pós Incremento
System.out.printf("Valor: %d\n", matriz[0][indice++]); //Imprime [0][indice] sem somar 1
// Soma 1 à indice
System.out.printf("Valor: %d\n", matriz[0][indice]); //Imprime [0][indice]
System.out.printf("Valor: %d\n", matriz[0][indice--]); //Imprime [0][indice] sem subtrair 1
// Subtrai 1 de indice
System.out.printf("Valor: %d\n", matriz[0][indice]); //Imprime [0][indice]
//Pré Incremento
System.out.printf("Valor: %d\n", matriz[0][++indice]); //Soma 1 à indice e então imprime [0][indice]
System.out.printf("Valor: %d\n", matriz[0][indice]); //Imprime [0][indice]
System.out.printf("Valor: %d\n", matriz[0][--indice]); //Subtrai 1 de indice e então imprime [0][indice]
System.out.printf("Valor: %d\n", matriz[0][indice]); //Imprime [0][indice]
}
}
3.5. Condicionais
C/C++
int main(void) {
int indice = 0;
//Pós Incremento
if(indice++ == 1){
printf("Indice é igual a 1\n");
}else{
printf("Indice não foi Atualizado\n");
}
// Indice Atualizado
printf("Indice: %d\n", indice);
if(indice-- == 0){
printf("Indice é igual a 0\n");
}else{
printf("Indice não foi Atualizado\n");
}
// Indice Atualizado
printf("Indice: %d\n", indice);
//Pós Incremento
if(++indice == 1){
printf("Indice é igual a 1\n");
}else{
printf("Indice não foi Atualizado\n");
}
printf("Indice: %d\n", indice);
if(--indice == 0){
printf("Indice é igual a 0\n");
}else{
printf("Indice não foi Atualizado\n");
}
printf("Indice: %d\n", indice);
return 0;
}
Java
class Main {
public static void main(String[] args) {
int indice = 0;
//Pós Incremento
if(indice++ == 1){
System.out.printf("Indice é igual a 1\n");
}else{
System.out.printf("Indice não foi Atualizado\n");
}
// Indice Atualizado
System.out.printf("Indice: %d\n", indice);
if(indice-- == 0){
System.out.printf("Indice é igual a 0\n");
}else{
System.out.printf("Indice não foi Atualizado\n");
}
// Indice Atualizado
System.out.printf("Indice: %d\n", indice);
//Pós Incremento
if(++indice == 1){
System.out.printf("Indice é igual a 1\n");
}else{
System.out.printf("Indice não foi Atualizado\n");
}
System.out.printf("Indice: %d\n", indice);
if(--indice == 0){
System.out.printf("Indice é igual a 0\n");
}else{
System.out.printf("Indice não foi Atualizado\n");
}
System.out.printf("Indice: %d\n", indice);
}
}
4. Evitando Erros
Como você pode perceber na prática a utilização do pós ou pré incremento pode resultar em algo inesperado desde que não se tenha um certo cuidado na hora de se programar. Isso não é problema para programadores experientes contudo para aqueles que estão começando existem algumas formas de se evitar tal problema como por exemplo:
- Sempre use a notação em pré incremento/decremento
- Evite incrementar/decrementar variáveis dentro de uma instrução de impressão, faça isso antes e então utilize a variável modificada.
- Incremente/Decremente índices de vetores e matrizes antes de indexar a matriz.
Entendendo esses conceitos nunca mais você cometerá algum erro envolvendo pós e pré incremento/decremento. Qualquer dúvida deixe nos comentários.
Até o próximo artigo!