====== Números racionais - alocação dinâmica ======
{{ :c:simpsons-panic.png?250|}}:!: Este projeto foi inicialmente proposto pelo prof. [[https://www.inf.ufpr.br/marcos/|Marcos Castilho]] para a disciplina de Programação 1 (CI1001).
Este trabalho visa modificar o módulo de [[números racionais]] desenvolvido anteriormente para usar alocação dinâmica de memória.
===== Atividade =====
Você deve implementar um programa que manipule números racionais, que são números da forma a/b, onde //a// e //b// são números inteiros. Nesta versão, os números racionais devem ser alocados dinamicamente.
Você deve baixar {{tp3.tgz|este arquivo}} e abri-lo para poder fazer o trabalho, pois irá precisar de todos os arquivos ali contidos:
* ''racional.h'': arquivo de cabeçalho com os protótipos das funções (**não deve ser alterado**).
* ''racional.c'': arquivo que implementa as operações sobre números racionais ("esqueleto" a completar).
* ''tp3.c'': código que usa a biblioteca de racionais ("esqueleto" a completar).
* ''makefile'': arquivo do utilitário "make" para compilar seu código.
* ''testes/*'': dados de entrada e de saída para testes.
* ''testa.sh'': script de teste.
No arquivo ''racional.h'' foi definida uma estrutura (//struct//) para o tipo abstrato de dados //racional// e os protótipos das funções que permitem manipular essa estrutura. Você deve implementar essas funções no arquivo ''racional.c''.
Este {{tp3.pdf |enunciado}} foi produzido pelo prof. Castilho para este projeto.
==== Programa principal ====
O programa principal (''tp3.c'') contém a função ''main''. Ele deve incluir o //header// ''racional.h'' e implementar corretamente o seguinte pseudocódigo:
leia um valor n tal que 0 < n < 100
aloque dinamicamente um vetor com n ponteiros para números racionais
preencha o vetor com n números racionais lidos da entrada
(leia o numerador e o denominador de cada racional)
imprima "VETOR = " e os racionais apontados pelo vetor
elimine do vetor os racionais inválidos
imprima "VETOR = " e o vetor resultante
ordene o vetor em ordem crescente
imprima "VETOR = " e os racionais apontados pelo vetor
calcule a soma dos racionais apontados pelo vetor
imprima "SOMA = " e a soma calculada acima
libere os racionais apontados pelo vetor
imprima "VETOR = " e os racionais apontados pelo vetor
libere o vetor de ponteiros
libere o espaço utilizado para fazer o cálculo da soma
retorne 0
==== Exemplos de funcionamento ====
O diretório ''testes/'' fornecido contém um conjunto de entradas e suas respectivas saídas esperadas. Considerando que o usuário informou como entrada o conteúdo de ''testes/entrada_1.txt'':
6
2 2
6 3
1 0
4 1
1 0
1 0
A saída correspondente deve ser esta (conteúdo de ''testes/saida_1.txt''):
VETOR = 1 2 NaN 4 NaN NaN
VETOR = 1 2 4
VETOR = 1 2 4
SOMA = 7
VETOR = NULL NULL NULL
==== Script de teste ====
Disponibilizamos um //script shell// para testar seu programa mais facilmente. Neste script fazemos uso de pipes combinado com o comando ''diff'', que faz a comparação das saídas geradas pelo programa com as saídas esperadas.
O uso do //script// é simples:
- ''./testa.sh 1'' : executa o programa e compara cada saída gerada com a saída esperada.
- ''./testa.sh 2'' : analisa a execução do programa usando a ferramenta Valgrind.
No **teste 1**, seu programa é executado para cada uma das entradas fornecidas no diretório ''testes/''. Se a saída do script for vazia para uma entrada é porque a saída gerada é igual à saída esperada, ou seja, seu programa tratou corretamente aquela entrada. Caso contrário, haverá uma saída neste formato:
3c3
< VETOR = 1 2 4
---
> VETOR = 1 2 3
Onde "<" indica uma linha no primeiro arquivo (saída gerada) e ">" a linha correspondente no segundo arquivo (saída esperada).
No **teste 2**, a ferramenta Valgrind executa seu programa e analisa as alocações, liberações e acessos à memória feitos por ele. Ela pode encontrar acessos inválidos, áreas não liberadas, uso de variáveis não inicializadas e outros problemas relacionados à memória. Caso seu programa esteja correto em relação ao uso da memória, o Valgrind deverá gerar estas mensagens:
All heap blocks were freed -- no leaks are possible.
...
ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Caso contrário, seu programa tem vazamentos e as mensagens de erro deverão indicar a causa. Outras mensagens que o Valgrind pode gerar são do tipo:
Invalid read of size 8
Invalid write of size 8
Conditional jump or move depends on uninitialised value(s)
...
Elas significam que seu programa, embora possa ter passado eventualmente pelo teste 1, ainda tem erros graves de acesso à memória e pode apresentar comportamento instável (pode falhar às vezes).
Caso seu programa apresente erros de memória ou comportamento instável no teste 1, você pode usar o teste 2 para obter mais informações sobre erros, usando o Valgrind.
===== Entregáveis =====
Entregue um único arquivo ''tp3.tgz'' que contenha por sua vez os seguintes arquivos:
* ''racional.h'': o mesmo arquivo fornecido, não o modifique
* ''racional.c'': sua implementação das funções definidas em ''racional.h''
* ''tp3.c'': contém a função ''main'' que usa os racionais
* ''makefile''