Code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
double pop (double stack[], int *stackSize);
void push (double stack[], int *stackSize, double x);
double multiply1 (double x, double y);
double add1 (double x, double y);
double neg1 (double x);
double divide1 (double x, double y);
double square1 (double x);
double squareRoot1 (double x);
double min1 (double x, double y);
double max1 (double x, double y);
double expo1 (double x, double y);
double pi (void);
double L (double x);
double E (double x);
typedef struct Operator //basic structure for all calculation functions
{
char symbol;
int operands;
union
{
void *f;
double (*f0)(void);
double (*f1) (double x);
double (*f2) (double x, double y);
};
}Operator;
double evaluate (const Operator op[], int opSize, const char * expression); //evaluate function prototype
int main (void)
{
char input[81]={'\0'}; //input array
Operator op[13]={{'*',2,multiply1}, {'+',2,add1}, {'-',1,neg1}, {'/',2,divide1}, {'S',1,square1},
{'s',1,squareRoot1}, {'m',2,min1}, {'M',2,max1}, {'^',2,expo1}, {'P',0,pi},
{'L',1,L}, {'e',1,E}}; //initializing array of structs
do{
printf("Enter your expression (nothing quits):\n");
fgets(input, sizeof(input), stdin);
printf("Answer: %lf\n", input[0]!='\n'?evaluate(op, 13, input):0.0); //makes output when quitting a little nicer
}while(input[0]!='\n');
}
double evaluate (const Operator op[], int opSize, const char * expression)
{
int i;
int indexSize; //actual size of the input
int *stackSize; //pointing to stackSize so I can manipulate stackSz in the push/pop functions
int stackSz=0; //integer for stackSize
double *stack; //pointer that will point to my malloc'd stack
double temp=0;
double temp2=0;
stackSize=&stackSz; //pointing to what is actually my stacksize in integer form
indexSize=strlen(expression); //gets the actual size of input
stack=malloc(indexSize*sizeof(double)); //malloc'ing a stack the size of the input
for (i=0; i<indexSize; ++i)
{
int k;
switch(expression[i]) //converts characters 0-9 to doubles and pushes, or finds the symbol.
{
case '0':
push(stack, stackSize, 0.0);
break;
case '1':
push(stack, stackSize, 1.0);
break;
case '2':
push(stack, stackSize, 2.0);
break;
case '3':
push(stack, stackSize, 3.0);
break;
case '4':
push(stack, stackSize, 4.0);
break;
case '5':
push(stack, stackSize, 5.0);
break;
case '6':
push(stack, stackSize, 6.0);
break;
case '7':
push(stack, stackSize, 7.0);
break;
case '8':
push(stack, stackSize, 8.0);
break;
case '9':
push(stack, stackSize, 9.0);
break;
default:
for (k=0; k<opSize; ++k) //iterate through all operators
{
if(expression[i]==op[k].symbol) //check if the operator equals that in the expression
{
switch(op[k].operands) //switch checks case to operands and evaluates from there
{
case 0:
push (stack, stackSize, op[k].f0());
break;
case 1:
temp=pop(stack, stackSize);
push (stack, stackSize, op[k].f1(temp));
break;
case 2:
temp=pop(stack, stackSize); //temp to guarantee args are evaluated properly
temp2=pop(stack, stackSize); //same as above
push (stack, stackSize, op[k].f2(temp2, temp));
break;
}
}
}
}
}
return stack[*stackSize];
free (stack);
}
double multiply1 (double x, double y) //multiplies two args
{
return x*y;
}
double add1 (double x, double y) //adds two args
{
return x+y;
}
double neg1 (double x) //sets arg to negative
{
return -x;
}
double divide1 (double x, double y) //divides two args
{
return x/y;
}
double square1 (double x) //squares an arg
{
return pow(x,2);
}
double squareRoot1 (double x) //takes square root of an arg
{
return sqrt(x);
}
double min1 (double x, double y) //takes minimum # of two #s
{
return x>y?x:y;
}
double max1 (double x, double y) //takes maximum # of two #s
{
return x>y?y:x;
}
double expo1 (double x, double y) //exponentiates x and y (x^y)
{
return pow(x,y);
}
double pi (void) //returns pi
{
return 3.1415926535;
}
double L (double x) //takes the log of the arg
{
return log(x);
}
double E (double x) //exponentiates the arg (e^x)
{
return exp(x);
}
double pop (double stack[], int *stackSize)
{
double value=0;
value=stack[*stackSize];
--*stackSize;
return value;
}
void push (double stack[], int *stackSize, double x)
{
++*stackSize;
stack[*stackSize]=x;
}