Aula Prática 2

Prazo de entrega: 1 semana (conferir no Moodle)

Exercício 1: Funções estatísticas

Um estatístico lhe procurou pois precisa de uma implementação em C de funções de densidade de probabilidade de três distribuições: Cauchy padrão, Gumbel e distribuição de Laplace. Assim, crie uma função que retorna a função de densidade de probabilidade \(f(x)\) para cada uma dessas distribuições, de acordo com as fórmulas abaixo.

Cauchy padrão: \(f(x) = \cfrac{1}{\pi(1+x^2)}\)

Gumbel: \(f(x; \mu, \beta) = \cfrac{1}{\beta}e^{-(z+e^{-z})}\), onde \(z = \frac{x-\mu}{\beta}\)

Laplace: \(f(x; \mu, b) = \cfrac{1}{2b}e^{\frac{-|x-\mu|}{b}}\)

Considere usar as funções exp(float x) para calcular \(e^x\) e fabs(float x) para calcular \(|x|\), ambas funções encontradas na biblioteca math.h. Exemplos fabs(-5.3) retorna 5.3 e exp(3) equivale a \(e^3\). Além disso, considere que \(\pi = 3.141592\). Por fim, note que além de \(x\), as funções podem ter outros parâmetros de entrada. A função densidade de probabilidade da distribuição de Laplace, por exemplo, tem como parâmetros de entrada \(x\), \(\mu\) e \(b\).

Crie e compile um módulo que contenha as funções estatísticas implementadas no exercício anterior.

Teste suas funções: Implemente um programa que use o módulo criado do exercício anterior para calcular a função densidade de probabilidade nos seguintes pontos:

cauchy(x = -2) = 0.063662
gumbel(x = 0, $\mu$ = 0.5, $\beta$ = 2) = 0.177786
laplace(x = -6, $\mu$ = -5, b=4) 0.097350

Exercício 2: Gerador de CPF

Números de CPF (Cadastro de Pessoa Física) possuem nove dígitos mais dois dígitos verificadores. As regras para cálculo dos digítos verificadores são as seguintes. Usaremos como exemplo o número 123456789:

  1. Calcule a soma dos produtos dos nove dígitos utilizando peso 2 para unidade, peso 3 para dezena, peso 4 para centena e assim sucessivamente. Exemplo: \(9 \times 2 + 8 \times 3 +7 \times 4 +6 \times 5 + 5 \times 6 + 4 \times 7 + 3 \times 8 + 2 \times 9 + 1 \times 10 = 210\).

  2. A dezena do número verificador é 0 caso o resto da divisão por 11 da soma dos produtos seja 0 ou 1. Caso contrário a dezena corresponde a subtrair de 11 o resto da divisão por 11 da soma dos produtos. Exemplo: o resto da divisão de 210 por 11 é 1, então a dezena do número verificador é 0.

  3. Calcule a soma dos produtos dos dez digitos, onde o digito menos significativo passa a ser a dezena dos digitos verificadores, utilizando os seguintes pesos: 2, 3, 4, 5, 6, 7, 8, 9, 10, 11. Exemplo: \(2 \times 0 + 3 \times 9 + 4 \times 8 + 5 \times 7 + 6 \times 6 + 7 \times 5 + 8 \times 4 + 9 \times 3 + 10 \times 2 + 11 \times 1 = 255\).

  4. A unidade do número verificador é 0 caso o resto da divisão da soma dos produtos por 11 seja 0 ou 1. Caso contrário a unidade corresponde a 11 menos o resto da divisão por 11 da soma dos produtos. Exemplo: resto da divisão de 255 por 11 é 2, então a unidade do número verificador é \(11 - 2 = 9\).

Escreva um programa para calcular o dígito verificador de CPF dados os nove dígitos do CPF. Para calcular resto de dívisão em C use o operador de módulo:

int x = 5 % 2; /* x = 1 */
int y = 21 % 3; /* y = 0 */
int z = 43 % 5; /* z = 3 */

Exemplo de resposta: O CPF 123.456.789 com dígitos verificadores é 123.456.789-09.

Exercício 3: Passagem de parâmetros por ponteiro e referência

Teoria

Nesta prática veremos a primeira utilidade clara de ponteiros, ou seja, de variáveis que podem armazenar endereços de memória. Como vimos na sala de aula, ponteiros são declarados da seguinte maneira:

int *ponteiro_para_inteiro;
float *ponteiro_para_float;

Para acessar o conteúdo de um endereço de memória, basta usar o operador * em qualquer variável de tipo ponteiro. Além disso, para descobrir e retornar o endereço de uma variável basta utilizar o operador & Exemplos:

int conta_corrente = 1234;
// ponteiro para inteiro recebe o endereço da variavel conta_corrente
int *p = &conta_corrente; 
printf("O endereco da variavel conta_corrente eh: %p \n", &conta_corrente);
printf("O conteudo do endereco armazenado pelo ponteiro p eh: %d\n", *p);
// podemos tambem alterar o valor da variavel apontada pelo ponteiro
*p = *p + 100;
printf("O endereco da variavel conta_corrente eh: %p\n", &conta_corrente); 
// conta corrente = 1334

Note que o operador * é usando para declarar uma variável do tipo ponteiro e para acessar o conteúdo de um endereço de memória, que pode estar armazenado em um ponteiro. Para mais informações sobre este operador, consulte os slides 20 ao 41 da Aula 4 publicada no site da disciplina (http://www.dcc.ufmg.br/~olmo/AEDS1.html).

Criação de um módulo

Criar um módulo modtroca com duas funções, uma de nome troca1 e outra de nome troca2. Você deve criar um arquivo modtroca.h com o cabeçalho das funções, um arquivo modtroca.c com a implementação das funções. Feito isso, você deve gerar um programa objeto modtroca.o, que deve ser ligado na compilação arquivo .c que contém o main (exercício seguinte).

Função troca1

Implementar uma função de nome troca1 que tem como parâmetros dois inteiros, valor1 e valor2, e não retorna nada. Essa função deve trocar os valores de valor1 e valor2 e imprimir os seus valores trocados. Exemplo: se a função receber como parâmetros valor1 = 32 e valor2 = 99, então a função deve imprimir a mensagem fim da função: valor1=99 e valor2=32 ao final da sua execução (ainda dentro da função).

Função troca2

Implementar uma função de nome troca2 que tem como parâmetros duas variáveis capazes de armazenar endereços de memória de inteiros (que tipo de variável é capaz de fazer isso?), end_valor1 e end_valor2. Essa função deve trocar o conteúdo dos endereços armazenados nessas variáveis, ou seja, o conteúdo armazenado pelo primeiro parâmetro deve ser armazenado no endereço do segundo parâmetro e vice-versa. Assim como na função anterior, essa função deve imprimir o conteúdo dos endereços de end_valor1 e end_valor2 ao final da sua execução.

Programa principal

Implemente um programa para usar e testar as funções do módulo criado. Para isso, neste programa, crie duas variáveis inteiras: x = 1 e y = 100. Depois disso, faça as seguintes operações:


Profs. Pedro O. S. Vaz de Melo e Ítalo F. S. Cunha