Desafio C
Tabela de despacho para operações matemáticas
Enunciado
Implemente uma calculadora simples usando uma tabela de despacho (array de ponteiros para função). O programa deve ler um operador (+, -, *, /) e dois números, e então executar a operação correspondente. Se o operador for inválido, imprima Operador invalido. Para divisão, se o divisor for zero, imprima Erro: divisao por zero.
Requisitos
- Definir funções
soma,subtrai,multiplicaedividecom assinaturadouble (double, double). - Criar um array de ponteiros para função para as quatro operações.
- Mapear os caracteres
+,-,*,/para índices do array (ex.: usandostrchrouswitch). - Tratar divisão por zero e operador inválido.
- Imprimir o resultado com duas casas decimais.
Código inicial
#include <stdio.h>
#include <string.h>
double soma(double a, double b) { return a + b; }
double subtrai(double a, double b) { return a - b; }
double multiplica(double a, double b) { return a * b; }
double divide(double a, double b) { return a / b; }
int main(void) {
char op;
double x, y;
// Leia operador e dois números
// Use tabela de despacho
return 0;
}
Saída esperada
Resultado: 8.00
Ver dica
Crie um array double (*ops[4])(double, double) = {soma, subtrai, multiplica, divide}; e uma string char *simbolos = "+-*/";. Use strchr para achar o índice; se não encontrar, operador inválido.
Mostrar solução
#include <stdio.h>
#include <string.h>
double soma(double a, double b) { return a + b; }
double subtrai(double a, double b) { return a - b; }
double multiplica(double a, double b) { return a * b; }
double divide(double a, double b) { return a / b; }
int main(void) {
// Tabela de despacho: array de ponteiros para função
double (*ops[4])(double, double) = {soma, subtrai, multiplica, divide};
const char *simbolos = "+-*/";
char op;
double x, y;
// Lê operador e dois números (ex.: "+ 5 3")
if (scanf(" %c %lf %lf", &op, &x, &y) != 3) {
printf("Entrada invalida\n");
return 1;
}
// Encontra o índice do operador na string de símbolos
const char *pos = strchr(simbolos, op);
if (pos == NULL) {
printf("Operador invalido\n");
return 1;
}
int idx = (int)(pos - simbolos);
// Trata divisão por zero
if (idx == 3 && y == 0.0) {
printf("Erro: divisao por zero\n");
return 1;
}
// Executa a operação via tabela
double resultado = ops[idx](x, y);
printf("Resultado: %.2f\n", resultado);
return 0;
}
Passo a passo
- Definimos as quatro funções de operação, todas com a mesma assinatura
double (double, double). - No
main, criamos o arrayopscom os ponteiros para essas funções. A ordem corresponde aos símbolos emsimbolos. - Lemos o operador e os dois números com
scanf. O espaço antes de%cignora espaços em branco. - Usamos
strchrpara localizar o operador na string"+-*/". Se não encontrar,poséNULLe imprimimos erro. - Calculamos o índice subtraindo o ponteiro inicial:
pos - simbolos. - Verificamos se é divisão (índice 3) e se o divisor é zero, tratando o erro.
- Chamamos a função apropriada através de
ops[idx](x, y)e imprimimos o resultado formatado.
Por que funciona
A tabela de despacho mapeia um índice (derivado do operador) diretamente para a função correta. Isso elimina uma cadeia de if/else ou switch, tornando o código mais limpo e fácil de estender. O uso de ponteiros para função permite que o array armazene funções e as chame dinamicamente.
Erros comuns
- Esquecer de tratar
strchrretornandoNULL; isso causaria acesso inválido ao calcular o índice. - Não verificar divisão por zero antes de chamar
divide, resultando eminfounan. - Misturar tipos: as funções devem retornar
doublee receberdouble. Se usarint, a tabela não compilará corretamente. - Ler o operador com
scanf("%c", &op)sem espaço antes pode capturar o\nda leitura anterior.
Outra forma de resolver
Usar switch em vez de tabela:
switch (op) {
case '+': resultado = soma(x, y); break;
case '-': resultado = subtrai(x, y); break;
// ...
}
Prefira a tabela quando houver muitas operações ou quando elas puderem ser configuradas em tempo de execução.
Saída esperada
Resultado: 8.00