C while

Até agora, cada linha dos seus programas rodou uma vez só, de cima para baixo. Mas boa parte do trabalho de um computador é repetir: mostrar os 30 alunos da turma, somar os preços de todos os produtos, perguntar de novo até a pessoa digitar algo válido. Para isso existem os laços (em inglês, loops). O mais simples deles é o while, que em inglês quer dizer "enquanto": enquanto a condição for verdadeira, repita.

Você vai aprender
  • O que é um laço e como escrever um while.
  • Como contar de 1 até 5, e de 5 até 1, com uma variável contadora.
  • Como acumular um resultado (uma soma) ao longo das voltas.
  • Como somar números digitados com scanf até o usuário digitar 0.
  • O que é um laço infinito e como pará-lo: Ctrl+C no terminal, botão Parar no editor.
  • Os avisos do compilador que pegam os erros mais comuns de while.

Todos os programas desta aula foram compilados com o gcc 15 na máquina fictícia da Ana (usuária ana, computador notebook), na pasta ~/c, com o comando padrão do guia: gcc -std=c23 -Wall -Wextra arquivo.c -o programa (veja Compilar com gcc). Você pode rodar cada um no editor do guia.


A ideia: "enquanto tiver louça, lave um prato"

Imagine que alguém deixou um bilhete para você: "Enquanto tiver louça na pia, lave um prato." Você não sabe quantos pratos há. Mesmo assim, a instrução funciona:

  1. Você olha a pia: tem louça? Sim → lava um prato.
  2. Olha de novo: tem louça? Sim → lava mais um.
  3. … e assim por diante …
  4. Olha de novo: tem louça? Não → acabou, você vai fazer outra coisa.

Repare em três detalhes, porque eles valem para todo while:

  • A pergunta vem antes de cada prato. Se a pia já estiver vazia, você não lava nenhum.
  • Cada volta muda alguma coisa (um prato a menos). Sem isso, a pergunta teria sempre a mesma resposta.
  • Quando a resposta vira não, você sai e continua com o resto do dia.

Em C, a "pergunta" é uma condição, igual à do if: uma expressão que dá verdadeiro ou falso. Em C, falso é o número 0 e verdadeiro é qualquer outro número. A diferença é que o if executa o bloco uma vez se a condição for verdadeira; o while executa de novo e de novo, enquanto ela continuar verdadeira.


1. O primeiro while: contar de 1 a 5

#include <stdio.h>

int main(void) {
    int i = 1;
    while (i <= 5) {
        printf("Volta %d\n", i);
        i++;
    }
    printf("Fim! i agora vale %d\n", i);
    return 0;
}
int i = 1;
A variável contadora, criada antes do laço, com o valor inicial. O nome i (de "índice") é uma tradição para contadores; poderia ser volta ou contador.
while
A palavra-chave do laço: "enquanto".
(i <= 5)
A condição, sempre entre parênteses. É testada antes de cada volta. Lê-se: "enquanto i for menor ou igual a 5" (os operadores estão em Operadores de Comparação).
{ … }
O corpo do laço: as linhas que se repetem. Cada execução do corpo se chama uma volta (ou iteração).
printf("Volta %d\n", i);
Mostra o valor atual de i no lugar do %d (veja Formatos do printf).
i++;
Soma 1 ao contador (veja ++ e --). É esta linha que faz o laço andar: sem ela, i seria 1 para sempre.
$ gcc -std=c23 -Wall -Wextra contar.c -o contar
$ ./contar
Volta 1
Volta 2
Volta 3
Volta 4
Volta 5
Fim! i agora vale 6

Passo a passo: o que o computador fez

Siga a variável i volta por volta. Este exercício de "ser o computador" é a melhor forma de entender laços:

MomentoValor de ii <= 5?O que acontece
1ª pergunta1verdadeiroEntra: mostra Volta 1, e i vira 2
2ª pergunta2verdadeiroMostra Volta 2, i vira 3
3ª pergunta3verdadeiroMostra Volta 3, i vira 4
4ª pergunta4verdadeiroMostra Volta 4, i vira 5
5ª pergunta5verdadeiroMostra Volta 5, i vira 6
6ª pergunta6falsoSai do laço e vai para a linha depois da }

Por isso a última linha mostra i agora vale 6: o laço só termina quando a condição fica falsa, e ela só fica falsa quando i passa de 5. A condição foi testada 6 vezes para o corpo rodar 5 vezes.

As três peças de todo laço com contador

1) início: int i = 1; · 2) condição: i <= 5 · 3) passo: i++. Se faltar qualquer uma, o laço dá errado. Guarde esse trio: na aula for, ele aparece todo numa linha só.

Missão: faça o programa contar até 10 em vez de 5. Depois experimente começar do 3 (troque o valor inicial) e veja quantas voltas sobram.

#include <stdio.h>

int main(void) {
    int i = 1;
    while (i <= 5) {
        printf("Volta %d\n", i);
        i++;
    }
    printf("Fim! i agora vale %d\n", i);
    return 0;
}
#include <stdio.h>

int main(void) {
    int i = 1;
    while (i <= 10) {
        printf("Volta %d\n", i);
        i++;
    }
    printf("Fim! i agora vale %d\n", i);
    return 0;
}

2. Contar para trás

O passo não precisa ser ++. Para uma contagem regressiva, comece do maior número, use -- e troque a condição para "maior que zero":

#include <stdio.h>

int main(void) {
    int segundos = 5;
    while (segundos > 0) {
        printf("%d...\n", segundos);
        segundos--;
    }
    printf("Já!\n");
    return 0;
}
$ gcc -std=c23 -Wall -Wextra regressiva.c -o regressiva
$ ./regressiva
5...
4...
3...
2...
1...
Já!

Quando segundos chega a 0, a pergunta 0 > 0 é falsa e o laço termina. O Já! fica fora das chaves, então aparece uma vez só, no fim.

O passo também pode ser de 2 em 2 (i += 2), de 10 em 10, ou até uma multiplicação (valor *= 2), como você vai ver na missão final. Os atalhos += e *= estão em Operadores de Atribuição.


3. Acumular: somar de 1 até 100

Um uso clássico de laço é ir juntando um resultado. A técnica tem duas variáveis com papéis diferentes:

  • o contador (n) diz em que volta estamos;
  • o acumulador (soma) guarda o total até agora. Ele começa em 0 e, a cada volta, recebe mais um pouco.
#include <stdio.h>

int main(void) {
    int soma = 0;
    int n = 1;
    while (n <= 100) {
        soma += n;
        n++;
    }
    printf("1 + 2 + ... + 100 = %d\n", soma);
    return 0;
}
$ gcc -std=c23 -Wall -Wextra soma100.c -o soma100
$ ./soma100
1 + 2 + ... + 100 = 5050

Nas primeiras voltas: soma vale 0, depois 0+1 = 1, depois 1+2 = 3, depois 3+3 = 6, depois 6+4 = 10… até chegar a 5050. Fazer isso à mão levaria um bom tempo; o computador faz as 100 voltas num piscar de olhos.

Crie (e zere) o acumulador fora do laço

Em C, uma variável criada sem valor (int soma;) começa com lixo: o que estava antes naquele pedaço da memória. Por isso o = 0 é obrigatório. E se a linha int soma = 0; ficar dentro das chaves, ela roda em toda volta e zera o total. Veja esse erro em Quando dá errado.

Quando você não sabe quantas voltas serão

O while brilha quando o número de voltas não é conhecido de antemão. A Ana guardou R$ 100 numa aplicação que rende 10% ao mês. Em quantos meses o dinheiro dobra?

#include <stdio.h>

int main(void) {
    double saldo = 100.0;
    int meses = 0;
    while (saldo < 200.0) {
        saldo = saldo * 1.10;
        meses++;
    }
    printf("Dobrou em %d meses: R$ %.2f\n", meses, saldo);
    return 0;
}
$ gcc -std=c23 -Wall -Wextra poupanca.c -o poupanca
$ ./poupanca
Dobrou em 8 meses: R$ 214.36

Aqui a condição não olha um contador, e sim o próprio saldo (um double, veja float e double). A variável meses só conta as voltas para mostrar no fim. O %.2f mostra o número com duas casas depois do ponto.


4. Somar números até o usuário digitar 0

Agora o programa vai conversar com a pessoa. A Ana quer somar os preços das compras: ela digita um número por vez e, quando terminar, digita 0. Ninguém sabe quantos números serão: é trabalho para o while. A leitura é feita com scanf ("scan formatted", ler formatado; veja Entrada com scanf).

#include <stdio.h>

int main(void) {
    int numero = 0;
    int soma = 0;
    printf("Digite um número (0 para parar): ");
    scanf("%d", &numero);
    while (numero != 0) {
        soma += numero;
        printf("Digite um número (0 para parar): ");
        scanf("%d", &numero);
    }
    printf("Soma: %d\n", soma);
    return 0;
}
scanf("%d", &numero);
A primeira leitura, antes do laço. Sem ela, o while não teria um número para testar. O & antes do nome diz ao scanf onde guardar o número.
while (numero != 0)
"Enquanto o número for diferente de zero." O 0 funciona como uma sentinela: um valor combinado que significa "acabou".
soma += numero;
Junta o número ao acumulador.
scanf("%d", &numero);
A leitura seguinte, no fim do corpo. É ela que muda a variável da condição. Depois dela, o laço volta para a pergunta numero != 0.
$ gcc -std=c23 -Wall -Wextra soma.c -o soma
$ ./soma
Digite um número (0 para parar): 10
Digite um número (0 para parar): 25
Digite um número (0 para parar): 7
Digite um número (0 para parar): 0
Soma: 42

O 0 não entra na soma: assim que ele é lido, a condição fica falsa e o laço termina antes do soma += numero. E se a primeira coisa digitada for 0, o corpo nem roda: a resposta é Soma: 0.

Repare que a pergunta e o scanf aparecem duas vezes (antes do laço e no fim do corpo). Isso funciona, mas é repetição. Logo abaixo você vê uma forma mais curta, e nas próximas aulas mais duas: o do while (pergunta primeiro, testa depois) e o laço infinito com break (break e continue).

No editor do guia, a entrada pode vir pronta

Na caixa abaixo, os números já estão prontos, um em cada linha, como se alguém digitasse um número e apertasse Enter de cada vez. O editor mostra cada número logo depois da pergunta que o leu, igual ao terminal acima. Nas caixas sem entrada pronta, o programa espera e você digita no terminal da própria caixa.

Missão: a entrada já traz 10, 25, 7 e 0. Crie uma segunda variável, quantos, que conta quantos números foram somados (sem contar o 0), e mostre no fim Você digitou 3 números. antes da soma.

#include <stdio.h>

int main(void) {
    int numero = 0;
    int soma = 0;
    printf("Digite um número (0 para parar): ");
    scanf("%d", &numero);
    while (numero != 0) {
        soma += numero;
        printf("Digite um número (0 para parar): ");
        scanf("%d", &numero);
    }
    printf("Soma: %d\n", soma);
    return 0;
}
#include <stdio.h>

int main(void) {
    int numero = 0;
    int soma = 0;
    int quantos = 0;
    printf("Digite um número (0 para parar): ");
    scanf("%d", &numero);
    while (numero != 0) {
        soma += numero;
        quantos++;
        printf("Digite um número (0 para parar): ");
        scanf("%d", &numero);
    }
    printf("Você digitou %d números.\n", quantos);
    printf("Soma: %d\n", soma);
    return 0;
}

E se a Ana digitar uma letra?

O scanf("%d", …) espera um número. Se a pessoa digitar abc, ele não consegue ler, deixa o abc parado na entrada e não muda a variável. Na volta seguinte, tenta de novo, encontra o mesmo abc, falha de novo… e o laço nunca termina, porque numero continua valendo 10:

$ ./soma
Digite um número (0 para parar): 10
Digite um número (0 para parar): abc
Digite um número (0 para parar): Digite um número (0 para parar): Digite um número (0 para parar): Digite um número (0 para parar): Digite um número (0 para parar): Digite um núm
^C                      « a pergunta se repete sem parar até a Ana apertar Ctrl+C

A defesa é conferir o que o scanf devolve: o número de valores que ele conseguiu ler. Com um %d, o certo é 1. Colocando a leitura dentro da condição, ela aparece uma vez só, e o laço também para quando a leitura falha:

#include <stdio.h>

int main(void) {
    int numero = 0;
    int soma = 0;
    printf("Digite um número (0 para parar): ");
    while (scanf("%d", &numero) == 1 && numero != 0) {
        soma += numero;
        printf("Digite um número (0 para parar): ");
    }
    printf("Soma: %d\n", soma);
    return 0;
}
scanf("%d", &numero) == 1
Tenta ler um número e confere se deu certo. É feito em toda pergunta do laço, inclusive a primeira.
&&
"E" (veja Operadores Lógicos). Só se a leitura deu certo o C olha a segunda parte.
numero != 0
A sentinela, como antes.
$ gcc -std=c23 -Wall -Wextra soma2.c -o soma2
$ ./soma2
Digite um número (0 para parar): 10
Digite um número (0 para parar): abc
Soma: 10

Agora uma letra encerra a soma em vez de travar o programa. (Avisar "isso não é um número, tente de novo" dá um pouco mais de trabalho: está em Validar a Entrada.)


5. Zero voltas: quando a condição já começa falsa

O while testa antes de entrar. Se a condição for falsa logo na primeira pergunta, o corpo não roda nenhuma vez, e o programa segue para a linha depois da }:

#include <stdio.h>

int main(void) {
    int estoque = 0;
    while (estoque > 0) {
        printf("Vendendo uma unidade...\n");
        estoque--;
    }
    printf("Acabou o estoque.\n");
    return 0;
}
$ gcc -std=c23 -Wall -Wextra nunca.c -o nunca
$ ./nunca
Acabou o estoque.

Isso não é erro: é exatamente o que você quer numa lojinha sem estoque. Quando precisar que o corpo rode pelo menos uma vez, a ferramenta é o do while.


6. O laço infinito

Se a condição nunca ficar falsa, o laço nunca termina. Isso se chama laço infinito, e o motivo mais comum é esquecer o passo. Neste programa, falta o i++, então i vale 1 para sempre e 1 <= 5 é sempre verdadeiro:

#include <stdio.h>

int main(void) {
    int i = 1;
    int dobro = 0;
    printf("Calculando...\n");
    while (i <= 5) {
        dobro = i * 2;
    }
    printf("Último dobro: %d\n", dobro);
    return 0;
}

O compilador não reclama: um laço infinito é um programa válido (às vezes ele é até de propósito, como num jogo que roda até o jogador sair). O problema só aparece ao rodar: o programa mostra Calculando... e fica parado, com o processador trabalhando a 100%, sem nunca chegar ao Último dobro.

Como parar no terminal: Ctrl+C

No terminal, aperte Ctrl+C. O terminal manda um aviso de "interromper" ao programa, que é encerrado na hora. O echo $? mostra o código de saída do último programa; 130 quer dizer "interrompido por Ctrl+C":

$ gcc -std=c23 -Wall -Wextra infinito.c -o infinito
$ ./infinito
Calculando...
^C                      « aqui a Ana apertou Ctrl+C
$ echo $?
130

Como testar sem medo: timeout

Quando você suspeita que um programa pode travar, rode-o com o comando timeout, que dá um prazo em segundos e encerra o programa se ele passar disso. É assim que os laços infinitos deste guia foram testados:

$ timeout 3 ./infinito
Calculando...            « e 3 segundos de espera
$ echo $?
124

O código 124 é o jeito do timeout dizer "o prazo acabou e eu tive que encerrar o programa". Se o programa tivesse terminado sozinho a tempo, o código seria o dele (normalmente 0).

Como parar no editor do guia: botão Parar (ou 15 segundos)

No editor, enquanto o programa roda, o botão Rodar vira ■ Parar. Clicar nele é o Ctrl+C do editor: aparece ^C e [código de saída: 130], como no terminal. Se você não fizer nada, o editor para o programa sozinho depois de 15 segundos rodando e mostra:

(o editor parou o programa: ele rodou mais de 15 segundos sem terminar — laço infinito?)
[programa interrompido]

Os 15 segundos contam só o tempo em que o programa está trabalhando. O tempo em que ele está esperando você digitar não conta.

Experimente: este é o programa travado. Clique em Rodar, espere aparecer Calculando... e clique em ■ Parar. Depois acrescente i++; dentro das chaves e rode de novo: agora ele termina e mostra Último dobro: 10.

#include <stdio.h>

int main(void) {
    int i = 1;
    int dobro = 0;
    printf("Calculando...\n");
    while (i <= 5) {
        dobro = i * 2;
    }
    printf("Último dobro: %d\n", dobro);
    return 0;
}

Como evitar

Antes de rodar um while, faça a si mesmo três perguntas:

  1. O que muda a cada volta? Alguma linha do corpo precisa mudar uma variável que aparece na condição (i++, segundos--, um novo scanf).
  2. A mudança vai na direção certa? Com while (i <= 5), o i precisa subir. Um i-- por engano faria i descer para sempre.
  3. O valor de parada é alcançável? Com while (i != 10) e i += 3 começando do 1, o i passa por 1, 4, 7, 10: para. Começando do 0, passa por 0, 3, 6, 9, 12… e pula o 10. Prefira < e <= a != em contadores.

Laço infinito de propósito: while (1) e while (true)

Às vezes você quer um laço sem fim, com uma saída escondida no meio do corpo, o break (aula break e continue). Como em C qualquer número diferente de zero é verdadeiro, a forma tradicional é while (1). No C23, true virou palavra da linguagem e while (true) também funciona C23. Num padrão antigo, o gcc não conhece o true sem o #include <stdbool.h>:

$ gcc -std=c17 -Wall -Wextra verdade.c -o verdade
verdade.c: In function ‘main’:
verdade.c:5:12: error: ‘true’ undeclared (first use in this function)
    5 |     while (true) {
      |            ^~~~
verdade.c:2:1: note: ‘true’ is defined in header ‘<stdbool.h>’; this is probably fixable by adding ‘#include <stdbool.h>’
    1 | #include <stdio.h>
  +++ |+#include <stdbool.h>
    2 | 

Com -std=c23 (ou sem -std, no gcc 15) o mesmo arquivo compila. Mais sobre isso em Booleanos.


Formas diferentes de escrever

Chaves num laço de uma linha

Como no if, se o corpo tiver uma única instrução, as chaves podem ser omitidas:

while (segundos > 0)
    printf("%d...\n", segundos--);

Funciona, mas é fácil acrescentar uma segunda linha achando que ela está dentro do laço. Use sempre as chaves: é o que este guia faz.

Onde fazer o passo

i++ numa linha separada (como nos exemplos) é a forma mais clara. Também existe printf("%d\n", i++);, que mostra e soma ao mesmo tempo. Para quem está começando, uma coisa por linha.

Qual laço usar?

SituaçãoLaço recomendado
Não sei quantas voltas serão (até o usuário digitar 0, até o saldo dobrar)while
O corpo precisa rodar pelo menos uma vez (menu, "deseja continuar?")do while
Sei quantas voltas serão (de 1 a 10, cada aluno da turma)for

Quando dá errado

O programa repete a mesma linha sem parar (esqueceu o passo)
#include <stdio.h>

int main(void) {
    int i = 1;
    while (i <= 5) {
        printf("Volta %d\n", i);
    }
    printf("Fim\n");
    return 0;
}
$ gcc -std=c23 -Wall -Wextra esqueci.c -o esqueci
$ ./esqueci
Volta 1
Volta 1
Volta 1
Volta 1
Volta 1
^C                      « milhares de linhas depois, a Ana apertou Ctrl+C

O que aconteceu: nada no corpo muda i, então i <= 5 é verdadeiro para sempre e a tela enche de Volta 1. No editor do guia, o programa é interrompido quando passa de 2 MB de saída: (o programa escreveu mais de 2 MB; o editor o interrompeu).

Como consertar: acrescente o passo (i++;) dentro das chaves.

Um ponto e vírgula depois do while ( … )
#include <stdio.h>

int main(void) {
    int i = 1;
    while (i <= 5); {
        printf("%d\n", i);
        i++;
    }
    return 0;
}
$ gcc -std=c23 -Wall -Wextra pontovirgula.c -o pontovirgula
pontovirgula.c: In function ‘main’:
pontovirgula.c:5:5: warning: this ‘while’ clause does not guard... [-Wmisleading-indentation]
    5 |     while (i <= 5); {
      |     ^~~~~
pontovirgula.c:5:21: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the ‘while’
    5 |     while (i <= 5); {
      |                     ^
$ timeout 3 ./pontovirgula
$ echo $?
124

O que significa: "esta cláusula while não protege… esta instrução, mas a indentação engana, como se ela estivesse protegida pelo while". O ; logo depois do parêntese é um corpo vazio: o laço é só while (i <= 5);, que repete "nada" para sempre, porque o i++ ficou fora dele. As chaves de baixo viraram um bloco comum, que nunca é alcançado. O programa nem mostra o 1.

No editor do guia, o Clang avisa com outras palavras: warning: while loop has empty body [-Wempty-body] ("o laço while tem corpo vazio").

Como consertar: apague o ; entre o ) e a {. Um while nunca leva ponto e vírgula ali (quem leva, no fim, é o do while).

"suggest parentheses around assignment used as truth value"
#include <stdio.h>

int main(void) {
    int numero = 5;
    while (numero = 0) {
        printf("%d\n", numero);
        numero--;
    }
    printf("Fim\n");
    return 0;
}
$ gcc -std=c23 -Wall -Wextra igual.c -o igual
igual.c: In function ‘main’:
igual.c:5:12: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
    5 |     while (numero = 0) {
      |            ^~~~~~
$ ./igual
Fim

O que significa: "sugiro parênteses em volta da atribuição usada como valor verdadeiro/falso". Um = sozinho é atribuição ("recebe"), não comparação. A condição numero = 0 guarda 0 em numero e vale 0, que é falso: o laço não rodou nenhuma vez. Com numero = 1, valeria sempre 1 (verdadeiro) e o laço seria infinito.

Como consertar: para comparar, use == ou, como aqui, !=: while (numero != 0). O Clang do editor dá o mesmo aviso (using the result of an assignment as a condition without parentheses) e ainda sugere: use '==' to turn this assignment into an equality comparison.

A soma não acumula (acumulador dentro do laço)
#include <stdio.h>

int main(void) {
    int n = 1;
    while (n <= 3) {
        int soma = 0;
        soma += n;
        printf("Soma até agora: %d\n", soma);
        n++;
    }
    return 0;
}
$ gcc -std=c23 -Wall -Wextra zera.c -o zera
$ ./zera
Soma até agora: 1
Soma até agora: 2
Soma até agora: 3

O que aconteceu: o esperado era 1, 3, 6. Como int soma = 0; está dentro das chaves, uma nova soma, valendo 0, é criada em cada volta. O compilador não avisa: o programa é válido, só faz outra coisa.

Como consertar: mova int soma = 0; para antes do while. Regra prática: o que deve sobreviver entre uma volta e outra nasce fora do laço.

O laço não roda nenhuma vez

O que aconteceu: a condição já era falsa na primeira pergunta, como no exemplo do estoque zerado. Às vezes é o certo; às vezes é a condição invertida (> no lugar de <) ou o contador começando no valor errado.

Como investigar: mostre a variável antes do laço (printf("i = %d\n", i);) e faça a tabela do passo a passo para a primeira pergunta.


Referência

FormaO que faz
while (condição) { … }Testa a condição; se verdadeira (diferente de 0), roda o corpo e testa de novo. Pode rodar 0 vezes.
int i = 1; while (i <= N) { …; i++; }Contador de 1 até N.
int i = N; while (i > 0) { …; i--; }Contagem regressiva de N até 1.
int soma = 0; … soma += x;Acumulador: nasce fora, valendo 0, e cresce dentro.
while (scanf("%d", &x) == 1 && x != 0) { … }Ler números até a sentinela (o 0) ou até a leitura falhar.
while (1) { … } / while (true) { … }Laço infinito de propósito; sai com break. true sem include só no C23.
Ctrl+CInterrompe um programa travado no terminal (código 130).
Botão ■ PararInterrompe o programa no editor do guia (que também para sozinho depois de 15 s).
timeout 3 ./programaRoda com prazo de 3 segundos (código 124 se estourar).

Exercícios

1. Complete a condição

Complete para o laço mostrar os números de 1 a 10:

int i = 1; while () { printf("%d\n", i); i++; }

2. O passo que falta

Complete o passo para esta contagem regressiva terminar:

int n = 3; while (n > 0) { printf("%d\n", n); }

3. Quanto vale no fim?

Depois de int i = 0; while (i < 4) { i++; }, quanto vale i?

4. Quantas vezes o corpo de int x = 10; while (x < 5) { x++; } roda?

5. int i = 1; while (i <= 5) { printf("%d", i); } — o que acontece?

6. No programa que soma até o 0, a Ana digitou abc e a pergunta passou a se repetir sem parar. Por quê?

7. Em C, qual destas condições é sempre verdadeira?

Missão final: dobrar até passar de 1000

Missão: a variável valor começa em 1. Enquanto ela for menor que 1000, mostre o valor (um por linha) e dobre-o. A saída deve ser 1, 2, 4… até 512 (o próximo, 1024, já passa de 1000). Use um while.

#include <stdio.h>

int main(void) {
    int valor = 1;
    // escreva o while aqui

    return 0;
}
#include <stdio.h>

int main(void) {
    int valor = 1;
    while (valor < 1000) {
        printf("%d\n", valor);
        valor *= 2;
    }
    return 0;
}

Resumo

  • while (condição) { corpo } repete o corpo enquanto a condição for verdadeira (diferente de 0). A condição é testada antes de cada volta, então o corpo pode rodar 0 vezes.
  • Todo laço com contador tem três peças: início (int i = 1;), condição (i <= 5) e passo (i++).
  • Um acumulador (soma) nasce fora do laço, valendo 0, e cresce dentro dele.
  • Para ler até uma sentinela (o 0), confira também o retorno do scanf: while (scanf("%d", &x) == 1 && x != 0).
  • Se nada muda a condição, o laço é infinito: pare com Ctrl+C no terminal (código 130), com ■ Parar no editor (que para sozinho em 15 s) e teste com timeout 3 (código 124).
  • Nada de ; logo depois de while ( … ), e = não é ==: o -Wall avisa os dois.