Saltar para o conteúdo
Topos Uranos

Resumo

A aula Do problema ao algoritmo reconheceu três formas de compor passos: a sequência, a decisão e a repetição. As duas primeiras já têm sua escrita em C++; esta aula dá à terceira a sua. Estuda as três formas do laço: while, que avalia sua condição antes de cada iteração e pode nunca executar seu corpo; do, que a avalia depois e o executa ao menos uma vez; e for, que reúne em uma linha a inicialização, a condição e o incremento da variável que governa a repetição. Mostra que as três expressam um mesmo mecanismo, de modo que cada uma se transforma nas outras, e ensina a escolher a mais clara; apresenta break e continue, que alteram o curso de uma iteração; e termina com os laços aninhados, cujo corpo interno se executa um número de vezes que se calcula com uma soma. O instrumento que acompanha toda a aula é a tabela de rastreamento: rastrear um laço à mão, iteração por iteração, é a maneira de prever quantas vezes seu corpo se executa e o que ele deixa ao sair.

Objetivos de aprendizagem

  1. Escrever um laço while, do ou for para uma repetição dada, escolhendo a forma mais clara.
  2. Rastrear à mão um laço com sua tabela de rastreamento e prever quantas vezes o corpo se executa.
  3. Transformar um laço de uma forma em outra conservando seu significado.
  4. Escrever laços aninhados e calcular quantas vezes o corpo interno se executa.

while

A forma de um while

Um while se escreve assim:

Código C++
while (condição) {    corpo}

Seu significado se enuncia em três passos: avalia-se a condição; se é falsa, o laço termina e a execução continua depois da chave que o fecha; se é verdadeira, executa-se o corpo e volta-se ao primeiro passo. Cada execução do corpo se chama uma iteração (ou volta). A condição é uma expressão booleana como as da aula Relações e lógica, e o corpo é um bloco; a regra das chaves que a aula Decisões fixou vale também aqui: o corpo de um laço leva sempre chaves, ainda que contenha uma única instrução.

Duas consequências se seguem da definição. A primeira: a condição se avalia antes de cada iteração, de modo que, se é falsa desde o começo, o corpo não se executa nenhuma vez. A segunda: para que o laço termine, o corpo deve mudar algo daquilo que a condição lê; se nada muda, a condição que foi verdadeira uma vez o será sempre. Ora, mudar não basta: a aula Do problema ao algoritmo mostrou que é preciso uma quantidade natural que decresça a cada iteração, a variante, e a aula Projetar laços corretos fará dela um método.

A divisão por subtrações sucessivas

O primeiro algoritmo com repetição do curso foi a divisão por subtrações sucessivas: enquanto o resto for ao menos o divisor, subtrai-se dele o divisor e soma-se um ao quociente. Escrito em C++, o algoritmo se transpõe quase palavra por palavra.

ExemploO quociente e o resto por subtrações
Programa em C++
#include <iostream>#include <print>​int main(){    int a{};    int b{};    std::cin >> a >> b;    int q{0};    int r{a};    while (r >= b) {        r -= b;        ++q;    }    std::println("{} = {} · {} + {}", a, b, q, r);}
Entrada do programa
23 7
Saída
23 = 7 · 3 + 2

As linhas 9 e 10 dão às variáveis seu valor inicial: ainda não se subtraiu nada, de modo que o quociente é 0 e o resto é todo o dividendo. A linha 11 é a condição do passo 2 do algoritmo; as linhas 12 e 13, o corpo. O programa supõe, como o algoritmo, que a≥0a \geq 0 e b>0b > 0: com b=0b = 0, a linha 12 não mudaria r e o laço não terminaria.

A tabela de rastreamento

Rastrear o laço à mão é preencher uma tabela: uma linha por iteração, uma coluna por variável e uma para a condição, avaliada ao começar a iteração. A linha 0 registra o estado antes da primeira avaliação; a última, a avaliação que resulta falsa e termina o laço.

ExemploO rastreamento de 23 por 7

Demonstração

  1. Antes do laço executam-se as linhas 9 e 10: q=0q = 0 e r=23r = 23. É a linha 0 da tabela; ainda não se avaliou a condição.

  2. Primeira iteração. A condição 23≥723 \geq 7 é verdadeira, de modo que se executa o corpo: rr passa a 16 e qq a 1. Depois a execução volta à linha 11.

  3. Segunda iteração. 16≥716 \geq 7 é verdadeira: rr passa a 9 e qq a 2.

  4. Terceira iteração. 9≥79 \geq 7 é verdadeira: rr passa a 2 e qq a 3.

  5. A quarta avaliação, 2≥72 \geq 7, é falsa: o corpo não se executa, o laço termina e a linha 15 escreve 23=7⋅3+223 = 7 \cdot 3 + 2.

O rastreamento ensina a contar. O corpo se executou três vezes, tantas quanto o quociente, e a condição se avaliou quatro: uma por iteração e uma a mais, a que falha. Essa relação vale para todo while que termina por sua condição: se o corpo se executa kk vezes, a condição se avalia k+1k + 1 vezes. E o caso extremo o confirma: com a entrada 5 7, a primeira avaliação, 5≥75 \geq 7, já é falsa, o corpo se executa zero vezes, e o programa escreve 5=7⋅0+55 = 7 \cdot 0 + 5, que é correto. Um while bem escrito atende sem código adicional o caso em que não há nada a repetir.