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) exp(x) Exponencial de x. Arcotangente de y/x, no intervalo [-π, π]. 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 rx ( ) x 0.5, se x 0.0 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) true B false S else R S 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 é [-2 31..2 31-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*10 308 (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))) = = 1000 powerless (161) = 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