whileé usado para ciclos em que a expressão é testada antes de executar o corpo do ciclo
do...whileé usado para ciclos em que a expressão é testada depois de executar o corpo
foré uma forma conveniente para ciclos com uma variável de controlo
whilewhile ( expressão ) instrução
Execução:
i = 1;
while (i < 10) /* expressão de controlo */
i = i * 2; /* corpo do ciclo */i = 1; |
|
i < 10? |
1 (verdade) |
i = i * 2 = 2 |
|
i < 10? |
1 (verdade) |
i = i * 2 = 4 |
|
i < 10? |
1 (verdade) |
i = i * 2 = 8 |
|
i < 10? |
1 (verdade) |
i = i * 2 = 16 |
|
i < 10? |
0 (falso) |
No final: i = 16.
whileO corpo pode ser um bloco de instruções em vez de uma só:
i = 1;
while (i < 10) {
printf("%d\n", i);
i = i * 2;
}Podemos colocar chavetas mesmo com uma só instrução:
i = 1;
while (i < 10) {
i = i * 2;
}while termina quando o valor da expressão for 0 (falso)
i < 10 então o ciclo termina quando \(i\geq 10\) while (1) {
... /* ciclo infinito */
}Limite superior: 5
1 1
2 4
3 9
4 16
5 25
/*
quadrados.c
Imprimir uma tabela de quadrados
*/
#include <stdio.h>
int main(void) {
int i, n;
printf("Limite superior: ");
scanf("%d", &n);
i = 1;
while (i <= n) {
printf("%d\t%d\n", i, i*i);
i ++;
}
return 0;
}/*
somar.c
Somar uma sequência de números
*/
#include <stdio.h>
int main(void) {
int n, soma = 0;
printf("Introduza valores; 0 termina.\n");
scanf("%d", &n); // primeiro valor
while (n != 0) { // enquanto não terminou
soma += n; // acumular
scanf("%d", &n); // ler próximo valor
}
printf("A soma é: %d\n", soma);
return 0;
}do...whiledo instrução while ( expressão );
Execução:
Vamos re-escrever o programa para somar números usando um ciclo do.
/*
somar2.c
Somar uma sequência de números (alternativa)
*/
#include <stdio.h>
int main(void) {
int n, soma = 0;
printf("Introduza valores; 0 termina.\n");
do {
scanf("%d", &n); // próximo valor
soma += n; // acumular
} while (n != 0); // enquanto não terminou
printf("A soma é: %d\n", soma);
return 0;
}Calcular o número de algarismos de um inteiro positivo:
Introduza um inteiro positivo: 5633
4 algarismo(s)
do é mais conveniente do que while porque qualquer número positivo tem pelo menos um algarismo/* algarismos.c
Contar algarismos de um inteiro positivo
*/
#include <stdio.h>
int main(void) {
int digits = 0, n;
printf("Inteiro positivo: ");
scanf("%d", &n);
do {
n /= 10; // quociente divisão por 10
digits ++; // mais um algarismo
} while (n > 0);
printf("%d algarismo(s)\n", digits);
return 0;
}forfor ( expr1; expr2; expr3 ) instruçãoexpr1 é a inicializaçãoexpr2 é a condição de repetiçãoexpr3 é a atualização após cada iteraçãoinstrução é o corpo do cicloExemplo:
for (i = 0; i < 10; i++)
printf("%d\n", i);forfor é conveniente para ciclos que necessitam de contar de um valor inicial até um valor finalwhile em vez do for, mas o for é mais claroforExemplo:
for (i = 0; i < 10; i++)
printf("%d\n", i);é equivalente a
i = 0;
while (i < 10) {
printf("%d\n", i);
i++;
}forA forma geral
for (expr1; expr2; expr3) instruçãoé equivalente a:
expr1;
while ( expr2 ) {
instrução
expr3;
}Esta tradução pode ajudar a compreender alguns detalhes.
forExemplo: qual o efeito de usar ++i em vez de i++ no ciclo seguinte?
for(i = 0; i < 10; ++i)
printf("%d\n", i);Traduzindo para while:
i = 0;
while (i < 10) {
printf("%d\n", i);
++i; // alternativa: i++;
}Usar ++i ou i++ é equivalente — contamos de 0 a 9.
forRepetir n vezes:
// contagem ascendente de 0 até n-1
for(i = 0; i < n; i++) ...
// contagem ascendente de 1 até n
for(i = 1; i <= n; i++) ...
// contagem descendente de n-1 até 0
for(i = n-1; i >= 0; i--) ...
// contagem descendente de n até 1
for(i = n; i > 0; i--) ...for< ou <=> ou >=== em vez <, <=, >, >=
i<n em vez de i<=nforPodemos omitir uma ou mais expressões no ciclo for.
Omitir a inicialização:
int i = 10;
for (; i > 0; i--)
printf("%d\n", i)Omitir a atualização:
int i;
for (i = 10; i > 0;)
printf("%d\n", i--)forOmitir ambas inicialização e atualização:
int i = 10;
for (; i > 0;)
printf("%d\n", i--)Isto é equivalente a um ciclo while:
int i = 10;
while (i > 0)
printf("%d\n", i--)forfor só termina se usarmos instruções de saida no corpo (mais à frente)for sem condição em vez de while para esses ciclos// usando ciclo while
while (1) {
...
}
// usando ciclo for
for (;;) {
...
}for em C99for pode ser substituida por uma declaraçãofor(int i = 0; i < n; i++) ...for em C99for(int i = 0; i < n; i++) {
printf("%d\n", i); // OK: i é válido
}
printf("%d\n", i); // ERRO: i fora de âmbito
printf("%d\n", n); // OK: n é válidobreakwhile ou fordo...whilebreak para terminar um ciclo em qualquer momentobreakExemplo: procurar o primeiro divisor próprio de um número \(n\) (isto é, um divisor entre 2 e \(n-1\)):
int i, n;
... /* obter valor de `n' */
for (i = 2; i < n; i++) {
if (n%i == 0) break;
}Este ciclo pode terminar de duas formas:
i >= n)i < n)breakNo final do ciclo podemos determinar a causa de terminação com um teste simples:
int i, n;
... /* obter valor de `n' */
for (i = 2; i < n; i++) {
if (n%i == 0) break;
}
if (i < n)
printf("Encontrou divisor: %d\n", i);
else
printf("Não tem divisores próprios\n");breakbreak é útil para escrever um ciclo com um teste de terminação a meiofor(;;) {
scanf("%d", &n);
if (n == 0) // se for zero
break; // terminar o ciclo
... // se não: processar o valor
}continuecontinue transfere a execução para o ponto imediatamente antes do fim do corpobreak termina o ciclo, continue continua no cicloLer e acumular 10 inteiros não-negativos.
int i = 0, n, soma = 0;
while (i < 10) {
scanf("%d", &n);
if (n < 0)
continue;
soma += n;
i ++;
/* continue salta para aqui */
}continue colocando instruções dentro de um ifn >= 0 em vez de n < 0int i = 0, n, soma = 0;
while (i < 10) {
scanf("%d", &n);
if (n >= 0) {
soma += n;
i ++;
}
}Uma instrução pode ser vazia, isto é, apenas um ponto-e-vírgula sem mais símbolos:
i = 0; ; j = 1; // segunda instrução vaziaUma instrução vazia não faz nada; é útil apenas para escrever um ciclo cujo corpo é vazio.
Considere o ciclo para procurar divisores:
for (i = 2; i < n; i++) {
if (n%i == 0) break;
}Podemos juntar as duas condições e retirar o break; o corpo fica vazio:
for (i = 2; i < n && n%i != 0; i++)
; /* instrução vazia */ Para evitar confusão, devemos escrever a instrução vazia numa linha separada.