Programação imperativa

Propaganda
Programação imperativa
3. Mais funções
3. Mais funções
Funções.
Escolha binária.
Números inteiros.
2
3. Mais funções
Funções.
Escolha binária.
Números inteiros.
3
As funções de cálculo
As funções de cálculo calculam um resultado a
partir dos argumentos, tal como na
matemática.
O tipo do
resultado.
O nome da
função.
A lista de argumentos, cada argumento
com o seu tipo.
double weighted_average(double lab, double exam)
{
return lab * 0.4 + exam * 0.6;
}
A instrução return.
A expressão que descreve os cálculos.
4
Distância entre dois pontos
Eis uma função que calcula a distância entre
dois pontos (x1, y1) e (x2, y2):
double distance (double x1, double y1,
double x2, double y2)
{
return sqrt(pow(x1-x2, 2) + pow(y1-y2, 2));
}
sqrt(x), a raiz quadrada de x.
pow(x, y), x elevado a y.
5
As funções de teste
Tipicamente, as funções de teste não têm argumentos
nem resultado, declaram variáveis para os dados e para
os resultados do problemas, leem os dados, calculam os
resultados e escrevem os resultados, repetidamente, até
não haver mais dados:
void test_distance(void)
{
double x1, y1;
double x2, y2;
double d;
while (scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2) != EOF)
{
d = distance(x1, y1, x2, y2);
printf("%f\n", d);
}
}
6
As funções matemáticas
Função
Significado
sin(x)
Seno de x.
cos(x)
Cosseno de x.
tan(x)
Tangente de x.
atan2(y, x)
Arcotangente de y/x, no intervalo [-π, π].
exp(x)
Exponencial de x.
log(x)
Logaritmo natural de x.
pow(x, y)
x elevado a y.
sqrt(x)
Raiz quadrada de x.
floor(x)
Maior número inteiro menor ou igual a x.
ceil(x)
Menor número inteiro maior ou igual a x.
fabs(x)
Valor absoluto de x.
Para usar, fazer
#include <math.h>
7
3. Mais funções
Funções.
Escolha binária.
Números inteiros.
8
Escolha binária
Por vezes, a expressão dos cálculos envolve a
escolha entre duas possibilidades: “a nota
final é a média ponderada (…) se a nota do
exame for maior ou igual a 8.5; caso contrário,
é a nota do exame (…)”.
double grade_exact(double lab, double exam)
{
return exam < 8.5 ? exam : weighted_average(lab, exam);
}
9
Expressão condicional
x ? y : z
O valor de x ? y : z é y, se x for verdadeiro, e é
z, se x for falso.
Se x for verdadeiro, z não é avaliado; se x é
falso, y não é avaliado.
double grade_exact(double lab, double exam)
{
return exam < 8.5 ? exam : weighted_average(lab, exam);
}
10
Arredondamento

  x  0.5 , se x  0.0
r ( x)  

  x  0.5 , se x  0.0
double round(double x)
{
return x < 0.0 ? ceil(x-0.5) : floor(x+0.5);
}
void test_round(void)
{
double x;
double z;
while (scanf("%lf", &x) != EOF)
{
z = round(x);
printf("%f\n", z);
}
}
11
Instrução if-else
Podemos usar a instrução if-else em vez da
expressão condicional:
double grade_exact(double lab, double exam)
{
if (exam < 8.5)
return exam;
else
return weighted_average(lab, exam);
}
double round(double x)
{
if (x < 0.0)
return ceil(x-0.5);
else
return floor(x+0.5);
}
12
Instrução if-else, significado
if (B)
S
else
R
true
S
B
false
R
13
Decomposição funcional
double grade_final(double lab, double exam)
{
return round(grade_exact(lab, exam));
}
A função grade_final chama as funções round
e grade_exact.
A função round chama as funções floor e ceil.
A função grade_exact chama a função
weighted_average.
14
Formatação dos números double
A nota final deve ser escrita sem parte decimal:
void test_grade_final(void)
{
double lb;
double ex;
double ge;
double gf;
while (scanf("%lf%lf", &lb, &ex) != EOF)
{
ge = grade_exact(lb, ex);
gf = grade_final(lb, ex);
printf("%.1f %.1f %f %.0f\n", lb, ex, ge, gf);
}
}
Usar uma casa
decimal.
Usar seis casas
decimais, por defeito.
Não usar nenhuma casa
decimal, nem sequer o ponto.
15
3. Mais funções
Funções.
Escolha binária.
Números inteiros.
16
Números inteiros
O tipo double representa os números reais; o tipo
int representa os números inteiros.
O intervalos dos números inteiros representáveis
é [-231..231-1], isto é,
[-2147483648.. 2147483647].
2147483647 é um pouco mais do que dois mil
milhões.
Para os reais o intervalo vai de 1.7*10-308 a
1.7*10308 (tanto positivos como negativos), com
precisão até 15 algarismos decimais.
Convém distinguir bem int e double.
17
Problema da potência minorante
A potência minorante de um número inteiro
positivo, para uma certa base, é a maior
potência dessa base que é menor ou igual ao
número.
Para a base 10, calcula-se de cabeça:
pm(3781) = 1000; pm(91) = 10; pm(100) =
100; pm(8) = 1.
Como programar?
18
Como não programar
Não vale fazer uma análise por casos
exaustiva:
int powerless10_very_bad(int x)
{
if (x < 10)
return 1;
else if (x < 100)
return 10;
else if (x < 1000)
return 100;
else if (x < 10000)
return 1000;
else ...;
}
19
Aproveitando a ideia…
Na verdade só há dois casos.
Se x é menor do que 10, o resultado é 1; se
não, o resultado é 10 vezes mais do que o
resultado que se obteria para um número 10
vezes menor do que x:
int powerless10(int x)
{
if (x < 10)
return 1;
else
return 10 * powerless10(x / 10);
}
20
Base 2
Em programação interessa-nos a base 2:
int powerless(int x)
{
if (x < 2)
return 1;
else
return 2 * powerless(x / 2);
}
Variante, com expressão condicional:
int powerless(int x)
{
return x < 2 ? 1 : 2 * powerless(x / 2);
}
21
Calculando à mão
powerless10(3785)
= 10 * powerless10(378)
= 10 * (10 * powerless(37))
= 10 * (10 * (10 * powerless(3)))
= 10 * (10 * (10 * 1)))
=…
powerless (161)
= 1000
= 2 * powerless(80)
= 2 * (2* powerless(40))
= 2 * (2 * (2 * powerless(20)))
= 2 * (2 * (2 * (2 * powerless(10))))
= 2 * (2 * (2 * (2 * (2 *powerless(5)))))
= 2 * (2 * (2 * (2 * (2 * (2 * powerless(2))))))
= 2 * (2 * (2 * (2 * (2 * (2 * (2 * powerless(1)))))))
= 2 * (2 * (2 * (2 * (2 * (2 * (2 * 1))))))
=…
= 128
22
Função de teste
void test_powerless(void)
{
int x;
int z;
while (scanf("%d", &x) != EOF)
{
z = powerless10(x);
printf("%d\n", z);
z = powerless(x);
printf("%d\n", z);
}
}
23
Concatenação de números
Queremos, dados dois números, calcular o
número que se obtém concatenando as
representações decimais desses números.
Por exemplo concat(356, 1278) vale 3561278;
concat(95, 6) vale 956; concat(81, 0) vale 810;
concat(0, 672) vale 672.
Como programar?
24
Como programar a concatenação
Se o segundo número for menor do que 10, é fácil:
multiplica-se o primeiro por 10 e soma-se o segundo.
E se não?
Se não, podemos começar por concatenar o primeiro
número e número que se obtém do segundo
eliminando o último algarismo; e depois
acrescentamos o último algarismo do segundo número
ao resultado.
Nota: o último algarismo é o resto da divisão por 10.
Nota: eliminar o último algarismo é dividir por 10.
Nota: Estamos a trabalhar com números inteiros: a
divisão é a divisão inteira.
25
Função de concatenação
Observe:
int concat(int x, int y)
{
if (y < 10)
return x * 10 + y;
else
return concat(x, y / 10) * 10 + y % 10;
}
Quociente da divisão inteira
de y por 10.
Resto da divisão inteira
de y por 10.
26
Função de teste
void test_concat(void)
{
int x;
int y;
int z;
while (scanf("%d%d", &x, &y) != EOF)
{
z = concat(x, y);
printf("%d\n", z);
}
}
27
Os operadores aritméticos
Operador
+
−
*
/
%
Significado
Soma.
Diferença.
Produto.
Quociente da divisão inteira, se ambos os
operandos forem de tipo int; quociente da
divisão exata, se algum deles (ou os dois)
forem de tipo double.
Resto da divisão inteira. Ambos os operandos
têm de ser de tipo int.
28
Os operadores de comparação
Operador
==
!=
<
<=
>
>=
Significado
Igualdade.
Não igualdade.
Menor.
Menor ou igual.
Maior.
Maior ou igual.
29
Download