No sé si habrás resuelto la duda, espero que si :).
Tengo que comentarte que la notación infija es bastante compleja de evaluar si se quiere dar soporte a más funciones con diferente aridad, ampliar el modelo a un intérprete etc. En su lugar veo mejor utilizar las notaciones prefija o postfija y evaluar la expresión mediante un autómata de pila. Si sigues interesado en el tema mirate esto:
[Enlace externo eliminado para invitados]
[Enlace externo eliminado para invitados]
[Enlace externo eliminado para invitados]
[Enlace externo eliminado para invitados]
De paso te dejo el código de la evaluación postfija implementada, solo habría que traducir la expresión infija a postfija antes de iniciar el proceso:
( La pila ha sido tomada de:
[Enlace externo eliminado para invitados] )
Código: Seleccionar todo
#include <stdio.h>
#define STACK_MAX 100
struct Stack {
int data[STACK_MAX];
int size;
};
typedef struct Stack Stack;
char isOperand(char);
int add(int,int);
int sub(int,int);
int div(int,int);
int mul(int,int);
void Stack_Init(Stack*);
void Stack_Push(Stack*,int);
void Stack_Pop(Stack*);
int Stack_Top(Stack*);
// mod,pow,or,and,xor ... Todas funciones binarias con aridad 2 en el ejemplo//
int main(int argc, char **argv)
{
// Primero habría que convertir notación infija (cómun) a postfija, da más flexibilidad para evaluar las expresiones complejas //
// Se obvia el proceso y se parte de la expresión ya obtenida //
char exp[] = "5 1 2 + 4 * + 3 -";
char* pExp = exp;
char op = 0x00;
// int(*pFnc)(int*); para generalizar la función viene bien un puntero a función y paso como parámetro un array de int (aridad genérica)
// p.e hacer aparte un gestor de funciones que devuelva el puntero a la función a llamar desde main. (Se elige int como se puede elegir
// cualquier otro tipo de datos)
Stack stk;
Stack_Init(&stk);
for(;*pExp!=0;pExp++){
if(*pExp!=' '){ // *pExp char '5' -> *pExp - 0x3A = valor === (*pExp - '0')
if(isOperand((op = *pExp-0x30))) Stack_Push(&stk,op);
else{ // Se asume por simplicidad que si no es un operando es una función, también se asume que las funciones toman únicamente 2 argumentos
op = *pExp;
// Se extraen los n argumentos y se pasan como parámetro a la función que toca
if(stk.size<2){ fprintf(stderr,"Faltan argumentos."); exit(0); }
else{
int y = Stack_Top(&stk);
Stack_Pop(&stk);
int x = Stack_Top(&stk);
Stack_Pop(&stk);
if(op=='+') Stack_Push(&stk,add(x,y));
else if(op=='-') Stack_Push(&stk,sub(x,y));
else if(op=='/') Stack_Push(&stk,div(x,y));
else if(op=='*') Stack_Push(&stk,mul(x,y));
// ... //
}
}
}
}
if(stk.size==1) fprintf(stdout,"Resultado: %d",Stack_Top(&stk));
else fprintf(stderr,"Has introducido demasiados elementos.");
return 0;
}
char isOperand(char i){
if(i>=0 && i<=9) return 1;
return 0;
}
// Ejemplo de definición de funciones para resolver expresiones //
int add(int x,int y){ return x+y; }
int sub(int x,int y){ return x-y; }
int div(int x,int y){ return x/y; }
int mul(int x,int y){ return x*y; }
void Stack_Init(Stack *S){
S->size = 0;
}
int Stack_Top(Stack *S){
if (S->size == 0) {
fprintf(stderr, "Error: stack empty\n");
return -1;
}
return S->data[S->size-1];
}
void Stack_Push(Stack *S, int d){
if (S->size < STACK_MAX){ S->data[S->size++] = d; }
else{ fprintf(stderr, "Error: stack full\n"); }
}
void Stack_Pop(Stack *S){
if (S->size == 0){
fprintf(stderr, "Error: stack empty\n");
}
else{
S->size--;
}
}
Un saludo :D