Material Extra - Laboratório: Revisão de Linguagem C
Este laboratório tem como objetivo revisar, através da prática, os principais recursos da linguagem C estudados nas Aulas 1b e 1c: funções, vetores, strings, passagem de parâmetros por valor e por referência (ponteiros), structs (incluindo o uso de typedef e do operador ->), arquivos texto e binários, e uma introdução simples à recursão.
O foco deste laboratório não está na complexidade dos algoritmos utilizados, mas sim na correta aplicação dos fundamentos da linguagem C. Todas as tarefas abaixo fazem parte de um único problema, dividido em itens que devem ser implementados na ordem apresentada.
Instruções Gerais.
|
Enunciado
Você deve implementar um pequeno sistema para cadastro e avaliação dos alunos de uma turma. Cada aluno é representado por uma struct, definida com typedef, contendo apenas seu nome, matrícula e média final.
Utilize as seguintes definições como ponto de partida do seu programa:
#include <stdio.h> #include <string.h> #define MAX 50 #define NUM_NOTAS 3 typedef struct { char nome[50]; int matricula; float media; } Aluno;
A partir dessas definições, implemente as funções descritas nos itens a seguir.
a) Leitura de um aluno (passagem por referência)
Implemente uma função que leia, via teclado, o nome e a matrícula de um aluno, armazenando-os na struct apontada por aluno, utilizando o operador -> para acessar seus campos.
void lerAluno(Aluno *aluno);
b) Leitura de um vetor de notas
Implemente uma função que leia, via teclado, n notas (float) e as armazene no vetor notas. Como vetores já são passados por referência em C, basta preencher as posições do vetor recebido.
void lerNotas(float notas[], int n);
c) Cálculo da média de um vetor de notas
Implemente uma função que receba um vetor de notas e a quantidade de notas nesse vetor, e retorne a média aritmética dessas notas.
float calcularMedia(float notas[], int n);
d) Atualização da média de um aluno (ponteiro + ->)
Implemente uma função que receba um ponteiro para um aluno e um valor de média já calculado, e atualize o campo media da struct apontada, utilizando o operador ->.
void atualizarMedia(Aluno *aluno, float media);
e) Impressão de um aluno (passagem por valor)
Implemente uma função que receba um aluno por valor (uma cópia da struct, e não um ponteiro) e imprima na tela seu nome, matrícula e média.
void imprimirAluno(Aluno aluno);
f) Contagem recursiva de aprovados
Implemente, de forma recursiva (sem for ou while), uma função que retorne quantos alunos do vetor possuem media >= 6.0. Defina o caso base (n == 0) e o caso recursivo, sobre o restante da turma.
int contarAprovados(Aluno turma[], int n);
g) Gravação da turma em arquivo binário
Implemente uma função que grave o vetor de alunos em um arquivo binário, cujo nome é recebido como parâmetro. Utilize as funções fopen() (modo "wb"), fwrite() e fclose(). Não esqueça de verificar se o arquivo foi aberto corretamente.
void salvarBinario(Aluno turma[], int n, char *nomeArquivo);
h) Geração de um relatório em arquivo texto
Implemente uma função que grave um relatório legível (arquivo texto, não binário) com os dados de todos os alunos da turma, um por linha, utilizando fprintf(). O nome do arquivo é recebido como parâmetro.
void gerarRelatorioTexto(Aluno turma[], int n, char *nomeArquivo);
Função main()
A função main() já está pronta e integra todas as funções descritas acima, na ordem em que devem ser chamadas. Utilize-a como roteiro: cada comentário indica exatamente qual item (a-h) deve estar implementado naquele ponto do programa.
int main() { Aluno turma[MAX]; float notas[NUM_NOTAS]; float media; int n, i; printf("Quantos alunos serão cadastrados? "); scanf("%d", &n); for (i = 0; i < n; i++) { // Item (a): leitura do aluno (nome e matrícula) por referência lerAluno(&turma[i]); // Item (b): leitura das notas em um vetor lerNotas(notas, NUM_NOTAS); // Item (c): cálculo da média do vetor de notas media = calcularMedia(notas, NUM_NOTAS); // Item (d): atualização da média do aluno via ponteiro (->) atualizarMedia(&turma[i], media); } printf("\n--- Dados da turma ---\n"); for (i = 0; i < n; i++) { // Item (e): impressão do aluno (passagem por valor) imprimirAluno(turma[i]); } // Item (f): contagem recursiva de aprovados printf("\nTotal de aprovados: %d\n", contarAprovados(turma, n)); // Item (g): gravação da turma em arquivo binário salvarBinario(turma, n, "turma.dat"); // Item (h): geração do relatório em arquivo texto gerarRelatorioTexto(turma, n, "relatorio.txt"); return 0; }
Resumo das funções a implementar
| Item | Protótipo | Conceito revisado |
|---|---|---|
| a | void lerAluno(Aluno *aluno); |
Passagem por referência (ponteiro), operador ->, strings |
| b | void lerNotas(float notas[], int n); |
Vetores, void |
| c | float calcularMedia(float notas[], int n); |
Vetores, retorno de valor |
| d | void atualizarMedia(Aluno *aluno, float media); |
Ponteiro para struct, operador -> |
| e | void imprimirAluno(Aluno aluno); |
Passagem de struct por valor |
| f | int contarAprovados(Aluno turma[], int n); |
Recursão (caso base e caso recursivo) |
| g | void salvarBinario(Aluno turma[], int n, char *nomeArquivo); |
Arquivos binários (fwrite) |
| h | void gerarRelatorioTexto(Aluno turma[], int n, char *nomeArquivo); |
Arquivos texto (fprintf) |
Entrega
|