Simule algoritmo no papel
Na disciplina de introdução à computação o professor pode escrever muito no quadro negro e você muito no papel. O computador só é usado quando você tem que escrever programas, em casa, para nota chamados de exercícios-programa. A menos que a carga horária em alguma universidade também inclua prática em laboratório. As provas também não são feitas num computador, mas à moda antiga, com papel e lápis. Nas provas não são exigidos programas complicados, apenas problemas de contagem e operações aritméticas.
Essencialmente, ler e corrigir algoritmo no papel é fazer o seu cérebro funcionar como um depurador.
- Pra que serve algoritmo no papel se não tem compilador?
Antes de um diretor de um filme filmar, tem um artista que desenha a cena. Antes de um arquiteto ter uma maquete 3D de uma casa tem um desenho no papel. Algoritmo no papel é pra você prestar atenção na lógica e não ficar "viciado" nos erros e avisos do compilador. O compilador identifica todos os erros de sintaxe, mas não pode fazer nada se o seu código tem operações redundantes que tomam tempo ou você esperava que imprimisse 10 vezes na tela "Olá mundo" mas o programa imprime só 9 vezes.
Simular no papel é o mesmo que acompanhar a execução do algoritmo linha por linha. Um modo de fazermos isso é tendo uma tabela, nas colunas colocamos as variáveis e nas linhas o valor das variáveis a cada operação feita. Isso é uma técnica útil para aprender como funcionam algoritmos feitos por outras pessoas. Se o algoritmo estiver bem documentado e bem escrito isso não é necessário, mas se estiver sem documentação e/ou muito mal escrito é a única forma de sabermos o que ele faz.
Um modo meio grosseiro de acompanhar a execução no computador mesmo é colocar um printf() em cada lugar que tiver uma variável e sempre colocar um antes e um depois de alguma operação, aí você lê a saída de tudo.
- Uma típica questão de simulação. Diga o que será impresso pelo programa abaixo:
#include <stdio.h> int main() { int matricula, i = 1, digito, inverte = 0, conta; printf("Digite o numero da sua matricula: "); scanf("%d", &matricula); conta = matricula; while (conta != 1) { conta = conta / 10; i = i * 10; } while (i != 0) { digito = matricula % 10; inverte = inverte + digito * i; printf("%d * ", inverte); if (digito % 2 == 0) printf("par\n"); else printf("impar\n"); matricula = matricula / 10; i = i / 10; } return 0; }
Façamos a simulação. Como exemplo suponha que a matrícula lida é 1234567:
primeiro while | ||
conta | i | iterações do laço |
1234567 | 1 | 0 (antes de entrar) |
123456 | 10 | 1 |
12345 | 100 | 2 |
... | ... | ... |
1 | 1000000 | 6 |
Se estiver bem adaptado à contagem e à operação de atribuição de valor, não precisa nem perder tempo simulando o primeiro laço do começo ao fim, simplesmente anote o valor do 'i' da última iteração.
Segundo while | printf | printf | ||||
i (antes) | matricula | digito | inverte | matricula | i (depois) | par / ímpar |
1.000.000 | 1234567 | 7 | 7000000 | 123456 | 100.000 | impar |
100.000 | 123456 | 6 | 7600000 | 12345 | 10.000 | par |
... | ... | ... | ... | ... | ... | ... |
10 | 12 | 2 | 7654320 | 1 | 1 | par |
1 | 1 | 1 | 7654321 | 0 | 0 | impar |
É bom deixar as variáveis ordenadas segundo a ordem de execução, assim evitamos algum erro de confusão entre variáveis ou operação simuladas fora de ordem. Se a variável aparece duas vezes, antes e depois de alguma operação, é bom diferenciar bem esses dois estados. Senão podemos confundir o valor da variável na sequência de iterações.
Se conseguir entender o que o algoritmo faz não precisa nem perder tempo com a tabela de simulação, já escreva a saída de cada chamada da função printf() imediatamente. Perceba: o primeiro laço atribui a 'i' o valor 10i, onde 'i' é o número de dígitos da matrícula menos um. O segundo laço faz a inversão dos dígitos da matrícula. Pega o último e põe no lugar do primeiro. Preenchendo o restante com zeros. A cada dígito removido, o algoritmo testa se o dígito é par ou ímpar.
Erros que as pessoas podem cometer numa prova com um algoritmo desse:
- Repetir uma vez a mais no primeiro laço. O que invariavelmente leva a um erro de contagem no segundo laço;
- Não saber como a variável do tipo inteiro lida com números não inteiros. 1234567 / 10 é o mesmo que remover o último dígito;
- Se a pessoa não entender o que é o sinal de igual, a operação de atribuição, não conseguirá fazer nada na simulação. Num caso desses não é raro a resposta da pessoa conter operações absurdas como multiplicar 1234567 * 10;
- Não saber qual o resto inteiro da operação x % y quando x < y, ou errar o resto;
- A cada repetição, a variável 'matricula' diminui de um dígito, enquanto a variável 'i' aumenta de um. Qualquer erro aí mostra falha na leitura do código e/ou falha na execução. A pessoa não acompanhou como deveria as operações aritméticas envolvidas;
- A impressão de "par" ou "ímpar" pode estar errada. Por algum motivo a pessoa confundiu a variável 'dígito' com a variável 'inverte';
- Um professor pode, se quiser, forçar uma indentação ruim ou usar nomes de variáveis menos óbvios para dificultar a simulação.
Erros com funções e vetores:
- Se a pessoa não entende o conceito de função e/ou vetor, não saberá simular a execução do algoritmo;
- Confundir ponteiros com variáveis, ou não saber o que fazem os ponteiros;
- Erros de contagem com relação a índices de vetores e matrizes;
- Não saber como funcionam funções recursivas.