Solicitação de algoritmo 4

Solicitação recebida de Caio da Silva Caetano. O problema encontrado no código dele é que a execução do código não gerava a média correta. Segue o enunciado e o código enviado.

Enunciado: fazer um programa para obter o nome e as 2 notas dos 28 alunos de uma turma. As notas serão informadas pelo professor. O programa deve calcular a média das 2 notas de cada aluno e exibir “Aprovado” caso a média seja igual ou superior a 7.0 e reprovado, caso contrário. Armazenar os valores em variável vetorial.

O código enviado mostra que foi pensado em utilizar uma matriz tridimensional para armazenar os alunos e suas notas. Como a matriz somente pode ser de um tipo e ela armazena dados numéricos e alfanuméricos, foi decidido corretamente em criar uma matriz de caracteres. Obviamente, ao armazenar os números nela, foi necessário fazer a conversão deles posteriormente para os cálculos.

Aqui vem uma primeira recomendação. A matriz criada é 3x3x28 e fica óbvio que uma dimensão de tamanho 3 é para guardar as 2 notas e o nome do aluno, outra dimensão de tamanho 3 é porque o algoritmo cumpre o enunciado apenas para 3 alunos (e não 28 como é pedido) e a dimensão de tamanho 28 se refere ao tamanho máximo do nome do aluno. Veja que esse tamanho 28 se confunde com o número de alunos do enunciado e por isso eu colocaria outro valor (eu coloquei o tamanho 30 no meu código). Também recomendo especificar o número de alunos como uma constante, para depois alterar somente o valor da constante e ter o meu código funcionando para 3 alunos durante os testes e 28 alunos para a conclusão do algoritmo.

Outra coisa é o uso da função gets(). É comum os compiladores mostrarem um warning ao utilizar essa função. Isso porque, se for informado um nome maior do que o definido (no caso, um nome com mais de 27 letras – isso porque o último caractere de uma string deve ser o ‘\0’), isso gerará um overflow do buffer (estouro de buffer). Uma função alternativa e que previne essa possibilidade de falha é a função fgets(). Muitos usam a função gets() porque aparece em material mais antigo sobre a linguagem C e também porque precisa receber apenas de um parâmetro (no caso, a variável a ser lida), mas a fgets() não é tão mais difícil de utilizar.

Para a função fgets(), informe a variável string a ser lida, o tamanho da string a ser lida e, considerando a entrada padrão (normalmente o teclado), o parâmetro stdin. No código do caso ficará fgets(vetor[i][0], 29, stdin). Lembrando que o tamanho 29 é porque o tamanho da variável para o nome está em é 30, mas é preciso deixar um caractere para receber o ‘\0’.

Veja que eu inicialmente fiz recomendações de melhorias. Agora vamos falar sobre o erro. Veja que no código foi corretamente utilizada a função atof() para converter a string no número.

Alterando o código para funcionar com a constante e a função fgets() teremos pouca diferença do anterior, mas ele segue a seguir. Eu também tirei a variável de nome vetor do escopo global e coloquei no escopo local porque não faz sentido ela no escopo global.

Teste o código em: https://ideone.com/yFRf93

Particularmente eu não teria utilizado a solução com a matriz tridimensional e sim com uma matriz para notas e outra para os nomes. Isso porque a estrutura tridimensional vai ser subutilizada. Para cada nota serão alocados 30 caracteres, sendo que 6 seria o máximo possível para elas. Além disso é preciso fazer a conversão de string para número o que, embora seja somente usar uma função, possui custo computacional associado. O código abaixo mostra essa opção de codificação.

Teste o código em: https://ideone.com/wdsXif

Complementando a solução proposta, segue a solução utilizando funções. Elaborei 3 funções para a solução, sendo uma para ler os dados, outra para calcular a média de cada aluno e uma terceira para mostrar se aluno está aprovado ou reprovado.

A função leituraDados() é um copia e cola de um trecho da função main(). Essa função e a mostraAprovacao() são funções que precisam receber as duas matrizes.

A função calcularMedias() somente precisa receber a matriz com as notas. Veja que para as médias foi necessário aumentar uma coluna na matriz de notas. Isso porque a matriz agora armazena as duas notas do aluno e a média das notas. Poderia ter feito o cálculo das médias na função mostraAprovacao(), dispensando inclusive a coluna adicional na matriz de notas, mas preferi dessa forma para facilitar o entendimento de todo o código (foi uma decisão pessoal e também achei didático mostrar que a função calcularMedias() precisa de menos parâmetros do que as demais).

Gosto sempre de destacar a vantagem na legibilidade do código que o uso de funções traz. Olhando para a função main(), fica claro ler o que o algoritmo faz.

Teste o código em: https://ideone.com/e6Se8c

Share

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.