Arrays de ponteiros para funções. Reescreva o programa da Figura 6.22 para que seja possível fazer uso de uma interface controlada por menus. O programa deverá oferecer ao usuário as quatro opções a seguir:

Digite uma escolha:

0 Imprime o array de notas

1 Acha a menor nota

2 Acha a maior nota

3 Imprime a média de todos os testes

para cada aluno

4 Encerra o programa

O uso de arrays de ponteiros para funções tem uma restrição: todos os ponteiros precisam ter o mesmo tipo. Os ponteiros precisam servir para funções com o mesmo tipo de retorno, que recebe argumentos do mesmo tipo. Por esse motivo, as funções na Figura 6.22 precisam

ser modificadas de modo que cada uma delas retorne o mesmo tipo e use os mesmos parâmetros. Modifique as funções minimum e maximum para imprimir os valores

mínimo e máximo, e não retornar nada. Para a opção 3, modifique a função average da Figura 6.22 para mostrar a média de cada aluno (e não de um aluno específico). A função average não deverá retornar nada, mas deverá usar os mesmos parâmetros de printArray, minimum e maximum. Armazene os ponteiros para as quatro funções no array processGrades e use a escolha feita pelo usuário como o subscrito do array que chama cada função.

Passo 1

Vamos modificar o programa que manipula as notas de três alunos e as exibe em formato de tabela, exibe a nota mínima e máxima e exibe a média em todas as quatro provas para cada um dos alunos, para que se torne um menu- programa orientado que usa uma matriz de ponteiros de função para chamar diferentes funções e executar diferentes tarefas.

Primeiro, vamos incluir a biblioteca e definir duas macros que irão representar o número de ALUNOS e de EXAMES.

Em seguida, escreveremos os protótipos de função para quatro funções. Aqui, devemos tornar todas as quatro funções nulas e usar as mesmas variáveis de parâmetro, para que possamos criar uma matriz de ponteiros de função para essas funções.

#include "stdio.h"

#define STUDENTS 3

#define EXAMS 4

void minimum(int grades[][EXAMS], size_t pupils, size_t tests);

void maximum(int grades[][EXAMS], size_t pupils, size_t tests);

void average(int grades[][EXAMS], size_t pupils, size_t tests);

void printArray(int grades[][EXAMS], size_t pupils, size_t tests);

Na função main(), vamos inicializar o array inteiro studentGrades com os valores das notas.

Declararemos uma variável int chamada choice e definiremos uma matriz de ponteiros de função chamada processGrades que armazenará 44 ponteiros de função para as quatro funções para as quais escrevemos os protótipos.

int main()

{

int studentGrades[STUDENTS][EXAMS] =

{ {77, 68, 86, 73},

{96, 87, 89, 78},

{70, 90, 86, 81} };

int choice;

void (*processGrades[4])(int[][EXAMS], size_t, size_t) =

{ printArray, minimum, maximum, average };

Passo 2

Executaremos um loop do-while controlado por sentinela para exibir um menu, exibir ao usuário todas as opções.

O usuário entrará com uma escolha e nós validaremos essa entrada. Em seguida, usaremos o valor choice para chamar uma das funções no array processGrades.

Assim que o usuário digitar o número 44, o loop será interrompido e o programa será encerrado.

do {

printf("Enter a choice:\n");

printf("%3d Print the array of grades\n", 0);

printf("%3d Find the minimum grade\n", 1);

printf("%3d Find the maximum grade\n", 2);

printf("%3d Print the average on all tests for each student\n", 3);

printf("%3d End program\n", 4);

do {

printf(">> ");

scanf("%d", &choice);

} while (choice choice > 4);

if (choice != 4) {

processGrades[choice](studentGrades, STUDENTS, EXAMS);

}

puts("");

} while (choice != 4);

}

A função mínimo()

Esta função será usada para encontrar a nota mínima e exibirá essa nota.

Primeiro, inicializaremos uma variável int lowGrade para 100100 (nota mais alta possível).

Em seguida, usaremos dois loops for aninhado para percorrer todas as notas e armazenar a nota mais baixa na variável lowGrade.

No final, esse valor será exibido.

void minimum(int grades[][EXAMS], size_t pupils, size_t tests)

{

size_t i;

size_t j;

int lowGrade = 100;

for (i = 0; i pupils; ++i) {

for (j = 0; j tests; ++j) {

if (grades[i][j] lowGrade) {

lowGrade = grades[i][j];

}

}

}

printf("\nLowest grade: %d\n", lowGrade);

}

Passo 3

A função máxima()

Esta função será usada para encontrar a nota máxima e exibi-la.

Primeiro, inicializamos uma variável int highGrade para 00 (menor nota possível).

Em seguida, usaremos dois loops for aninhados para percorrer todas as notas e armazenar a nota mais alta na variável highGrade.

No final, esse valor será exibido.

void maximum(int grades[][EXAMS], size_t pupils, size_t tests)

{

size_t i;

size_t j;

int highGrade = 0;

for (i = 0; i pupils; ++i) {

for (j = 0; j tests; ++j) {

if (grades[i][j] > highGrade) {

highGrade = grades[i][j];

}

}

}

printf("\nHighest grade: %d\n", highGrade);

}

A função média()

Esta função será chamada para exibir a nota média de cada um dos alunos.

Vamos definir um array int chamado total e inicializar seus três elementos com 00.

Em seguida, usaremos dois loops for aninhados para adicionar as notas de cada linha do array grades ao elemento correspondente do array total.

No final, exibiremos as notas médias de cada aluno. Vamos obtê-los dividindo os valores da matriz total pelo número de testes.

void average(int grades[][EXAMS], size_t pupils, size_t tests)

{

size_t i;

size_t j;

int total[STUDENTS] = { 0 };

for (i = 0; i pupils; ++i) {

for (j = 0; j tests; ++j) {

total[i] += grades[i][j];

}

}

printf("\n");

for (i = 0; i pupils; ++i) {

printf("The average grade for student %u is %.2f\n",

i, (double)total[i] / tests);

}

}

A função printArray()

Esta função permanece inalterada.

Ele é usado para exibir todas as notas em formato tabular. Para fazer isso, ele usa dois loops for aninhados. Os subscritos do teste são exibidos como o cabeçalho da tabela e os subscritos dos alunos são exibidos à esquerda da tabela.

void printArray(int grades[][EXAMS], size_t pupils, size_t tests)

{

size_t i;

size_t j;

printf("\n%s", " [0] [1] [2] [3]");

for (i = 0; i pupils; ++i) {

printf("\nstudentGrades[%d] ", i);

for (j = 0; j tests; ++j) {

printf("%-5d", grades[i][j]);

}

}

puts("");

}

Resposta

O código final:

#include "stdio.h"

#define STUDENTS 3

#define EXAMS 4

void minimum(int grades[][EXAMS], size_t pupils, size_t tests);

void maximum(int grades[][EXAMS], size_t pupils, size_t tests);

void average(int grades[][EXAMS], size_t pupils, size_t tests);

void printArray(int grades[][EXAMS], size_t pupils, size_t tests);

int main()

{

int studentGrades[STUDENTS][EXAMS] =

{ {77, 68, 86, 73},

{96, 87, 89, 78},

{70, 90, 86, 81} };

int choice;

void (*processGrades[4])(int[][EXAMS], size_t, size_t) =

{ printArray, minimum, maximum, average };

do {

printf("Enter a choice:\n");

printf("%3d Print the array of grades\n", 0);

printf("%3d Find the minimum grade\n", 1);

printf("%3d Find the maximum grade\n", 2);

printf("%3d Print the average on all tests for each student\n", 3);

printf("%3d End program\n", 4);

do {

printf(">> ");

scanf("%d", &choice);

} while (choice choice > 4);

if (choice != 4) {

processGrades[choice](studentGrades, STUDENTS, EXAMS);

}

puts("");

} while (choice != 4);

}

void minimum(int grades[][EXAMS], size_t pupils, size_t tests)

{

size_t i;

size_t j;

int lowGrade = 100;

for (i = 0; i pupils; ++i) {

for (j = 0; j tests; ++j) {

if (grades[i][j] lowGrade) {

lowGrade = grades[i][j];

}

}

}

printf("\nLowest grade: %d\n", lowGrade);

}

void maximum(int grades[][EXAMS], size_t pupils, size_t tests)

{

size_t i;

size_t j;

int highGrade = 0;

for (i = 0; i pupils; ++i) {

for (j = 0; j tests; ++j) {

if (grades[i][j] > highGrade) {

highGrade = grades[i][j];

}

}

}

printf("\nHighest grade: %d\n", highGrade);

}

void average(int grades[][EXAMS], size_t pupils, size_t tests)

{

size_t i;

size_t j;

int total[STUDENTS] = { 0 };

for (i = 0; i pupils; ++i) {

for (j = 0; j tests; ++j) {

total[i] += grades[i][j];

}

}

printf("\n");

for (i = 0; i pupils; ++i) {

printf("The average grade for student %u is %.2f\n",

i, (double)total[i] / tests);

}

}

void printArray(int grades[][EXAMS], size_t pupils, size_t tests)

{

size_t i;

size_t j;

printf("\n%s", " [0] [1] [2] [3]");

for (i = 0; i pupils; ++i) {

printf("\nstudentGrades[%d] ", i);

for (j = 0; j tests; ++j) {

printf("%-5d", grades[i][j]);

}

}

puts("");

}