Você está na página 1de 29

Programação imperativa

5. Ciclos
5. Ciclos
Ciclos while.
Ciclos for.
Operadores de afetação.
O problema “3x+1”.

2
5. Ciclos
Ciclos while.
Ciclos for.
Operadores de afetação.
O problema “3x+1”.

3
Ciclos while
Já conhecemos. Por exemplo:
void test_sum(void)
{
int x;
int z = 0;
while (scanf("%d", &x) != EOF)
z += x;
printf("%d\n", z);
}
Este programa soma os números lidos da consola
até ao fim dos dados (Ctrl-Z).
4
Contando os números
É uma variante do anterior:
void test_count(void)
{
int x;
int z = 0;
while (scanf("%d", &x) != EOF)
z++;
printf("%d\n", z); 41 228
6 12 8 9
12
} 1 9 5 7 23 1
7 77 12 9 39 1 77 8 1
2 4
^Z
25

5
Encontrando o maior de todos
INT_MIN é a constante
É ainda outra variante: simbólica que
representa o mínimo
void test_max(void) valor existente no tipo
{ int. Precisa de #include
int x; <limits.h>.

int z = INT_MIN;
while (scanf("%d", &x) != EOF)
if (z < x)
3 7 12 77 3 8
z = x; 127 6 38 289 1 72 61
printf("%d\n", z); 6 34 256 200
8 45 199 12
} 1 16 14 95
^Z
289

6
Divisões sucessivas
Quantas vezes é preciso dividir um número ao
meio para atingir 1?
int halving(int x)
100
{ void test_halving(void) 6
int result = 0; { 128
int x; 7
while (x >= 2) int z; 127
{ while (scanf("%d", &x) != EOF) 6
1
x /= 2; {
0
z = halving(x);
result++; printf("%d\n", z);
2
1
} } 1024
return result; } 10
^Z
}
7
Quantos algarismos tem um número?
Dividamos por 10, sucessivamente, contando,
até atingir um número menor que 10:
int count_digits(int x)
450
{
void test_count_digits(void) 3
int result = 1; { 999
while (x >= 10) int x; 3
{ int z; 987598
while (scanf("%d", &x) != EOF) 6
x /= 10;
{ 1000
result++; z = count_digits(x); 4
} printf("%d\n", z); 6
return result; } 1
} 2000000000
}
10
É muito parecido com
^Z
o anterior.

8
Instrução while, significado

while (B) B
false
S true

9
5. Ciclos
Ciclos while.
Ciclos for.
Operadores de afetação.
O problema “3x+1”.

10
Ciclos for
Se o número de números que queremos somar for
indicado, usamos um ciclo for. Observe:
void test_sum_some(void) 12:17:31.68>gcc -Wall m_loops.c
{ 12:37:52.37>a
int x; 5
int n; 8 9 2 3 6
28
int z = 0;
int i; 12:38:14.70>a
5
scanf("%d", &n); 8 9
for (i = 0; i < n; i++) 6 7
3 40
{ 33
scanf("%d", &x);
z += x; 12:38:37.93>a
10
} 1 2 3 4 5 6 7 8 9 10
printf("%d\n", z); 55
} 11
O máximo dos n números lidos
void test_max_some(void)
{
int x; 12:49:25.55>gcc -Wall m_loops.c
int n; 12:49:36.65>a
int z = INT_MIN; 4
23 45 7 17
int i; 45
scanf("%d", &n);
for (i = 0; i < n; i++) 12:49:46.57>a
10
{ 7 23 56 129 56 111 12 17 12 95
scanf("%d", &x); 129
if (z < x) 12:50:43.10>a
z = x; 6
12 78 45 12 79 10 34 299 17
} 79
printf("%d\n", z);
}

12
Potência inteira
X elevado a Y: 13:19:30.47>a
2 5
int power(int x, int y) 32
10 6
{ 1000000
int result = 1; 5 5
3125
int i; 3 9
19683
for (i = 0; i < y; i++) 1 10
result *= x; void test_power(void) 1
999 0
{
return result; int a;
1
^Z
} int b;
int z;
while (scanf("%d%d", &a, &b) != EOF)
{
z = power(a, b);
printf("%d\n", z);
}
}
13
Fatorial
O fatorial de X é o produto de todos os
números inteiros no intervalo [1..X]:
int factorial(int x)
{
int result = 1;
int i;
for (i = 2; i <= x; i++)
result *= i;
return result;
}
14
Testando o fatorial Testando para n = 20.

0 1
O fatorial cresce muito depressa, e 1 1
2 2
rapidamente causa overflow: 3 6
4 24
void test_factorial_table(int n) 5 120
6 720
{ 7 5040
int z; 8 40320
9 362880
int i; 10 3628800
for (i = 0; i < n; i++) 11 39916800
12 479001600
{ 13 1932053504
z = factorial(i); 14 1278945280
15 2004310016
printf("%d %d\n", i, z); 16 2004189184
} Este valores são disparatados, 17 -288522240
} pois os cálculos já excederam 18 -898433024
o maior número inteiro 19 109641728
representável. 15
Fatorial com doubles
Com double, conseguimos ir mais longe:
double dfactorial (int x)
{
double result = 1.0;
int i;
for (i = 2; i <= x; i++)
result *= i;
return result;
}

16
Testando o fatorial com double 0 1
1 1
Observe: 2 2
3 6
Testando para n = 30.
4 24
void test_dfactorial(void) 5 120
6 720
{ 7 5040
8 40320
int x; 9 362880
double z; 10 3628800
11 39916800
while (scanf("%d", &x) != EOF) 12 479001600
13 6227020800
{ 14 87178291200
z = dfactorial(x); 15 1307674368000
16 20922789888000
printf("%.0f\n", z); 17 355687428096000
18 6402373705728000
} 19 121645100408832000
} 20 2432902008176640000
21 51090942171709440000
22 1124000727777607700000
A partir de fatorial de 22, os valores não 23 25852016738884978000000
24 620448401733239410000000
são exatos, por falta de precisão dos 25 15511210043330986000000000
números double. Por exemplo 22! vale 26 403291461126605650000000000
27 10888869450418352000000000000
1124000727777607680000 e 29! vale 28 304888344611713840000000000000
8841761993739701954543616000000. 17
29 8841761993739700800000000000000
Instrução for, significado

A
for (A;B;C)
S C B
false

true

18
5. Ciclos
Ciclos while.
Ciclos for.
Operadores de afetação.
O problema “3x+1”.

19
Operadores de afetação
O significado dos operadores de afetação +=,
−=, *=, /= e %= é “intuitivo”:
Utilização Significado
x += y x=x+y
x −= y x=x−y
x *= y x=x*y
x /= y x=x/y
x %= y x=x%y
20
Incrementação, decrementação
O operador de incrementação é ++ e o de
decrementação é −−:

Utilização Efeito
x++ x=x+1
x−− x=x−1

21
5. Ciclos
Ciclos while.
Ciclos for.
Operadores de afetação.
O problema “3x+1”.

22
Problema 3x+1
Considere a seguinte função:
3x  1 , se x for ímpar.
f ( x)  
 x / 2, se não.
Qualquer que seja x, a sequência x, f(x), f(f(x)), f(f(f(x))),
etc., acaba por alcançar o valor 1. Isto é uma conjetura,
não um teorema.
Para um dado x, a sequência finita que começa em x e
termina em 1 é o ciclo de x.
Queremos calcular o comprimento do maior ciclo para os
valores de um intervalo dado.
Este é o primeiro problema da coleção de problemas UVa, o mais famoso arquivo
de problemas de programação da Internet: http:/uva.onlinejudge.org/. Veja
http://uva.onlinejudge.org/external/1/100.html. 23
A função 3x+1
Eis a função:
int f(int x)
{
return x % 2 == 1 ? 3 * x + 1 : x / 2;
}
Observando o ciclo:
void show_cycle(int x)
{
while (x != 1)
{
printf("%d ", x);
x = f(x);
}
printf("%d\n", x);
} 24
Observando vários ciclos
void test_show_cycles(void)
{
int x1, x2;
int i;
while (scanf("%d%d", &x1, &x2) != EOF)
for (i = x1; i <= x2; i++)
show_cycle(i);
} 17:19:34.09>a
22 25
22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
23 70 35 106 53 160 80 40 20 10 5 16 8 4 2 1
24 12 6 3 10 5 16 8 4 2 1
25 76 38 19 58 29 88 44 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
1 8
1
2 1
3 10 5 16 8 4 2 1
4 2 1
5 16 8 4 2 1
6 3 10 5 16 8 4 2 1
7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
8 4 2 1
^Z
25
O comprimento do maior ciclo
int max_cycle_len(int x1, int x2)
{
int result = INT_MIN;
int i;
for (i = x1; i <= x2; i++)
{
int z = cycle_len(i);
if (result < z)
result = z;
}
return result;
}

26
Tarefa
void uva_100(void)
{
int x1;
int x2;
int z;
while (scanf("%d%d", &x1, &x2) != EOF)
{
z = max_cycle_len(x1, x2);
printf("%d %d %d\n", x1, x2, z);
} 17:31:54.91>a
1 10
} 1 10 20
100 200
100 200 125
201 210
201 210 89
900 1000
900 1000 174
^Z 27
Variante
Mostrar também o ciclo de comprimento máximo;
em caso de empate, escolher o de menor x.
Eis a função que int max_cycle(int x1, int x2)
{
calcula o ciclo de int result = -1;
comprimento int maxlen = INT_MIN;
int i;
máximo. for (i = x1; i <= x2; i++)
{
Note que a função int z = cycle_len(i);
anterior calculava o if (maxlen < z)
{
comprimento do ciclo maxlen = z;
de comprimento result = i;
}
máximo. }
return result;
} 28
Nova tarefa
void uva_100_2(void)
{
int x1;
int x2;
int z;
int w;
while (scanf("%d%d", &x1, &x2) != EOF)
{
z = max_cycle(x1, x2);
w = cycle_len(z);
printf("%d %d %d %d\n", x1, x2, z, w);
show_cycle(z);
}
17:50:00.34>a
} 10 15
10 15 14 18
14 7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
16 20
16 20 18 21
18 9 28 14 7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
^Z 29

Você também pode gostar