逆ポーランド記法電卓 C言語
#include <stdio.h>
#include <conio.h>
#include <math.h>
#define STACK_SIZE 10
#define NUM_DIGITS 8
typedef enum _OPERATION
{
OPE_PLUS,
OPE_MINUS,
OPE_MULTIPLY,
OPE_DIVIDE,
OPE_INVERSION,
OPE_CLEAR,
OPE_ENTER,
OPE_EXIT
}OPERATION;
typedef enum _STACK_ERROR
{
ERR_NONE,
ERR_OVERFLOW,
ERR_EMPTY
}STACK_ERROR;
typedef struct
{
double values[STACK_SIZE];
int count;
STACK_ERROR error;
}CALC_STACK;
void Push( CALC_STACK* pstack, double value)
{
if (pstack->count < STACK_SIZE)
pstack->values[pstack->count++] = value;
else
pstack->error = ERR_OVERFLOW;
}
double Pop( CALC_STACK* pstack)
{
if (pstack->count > 0)
{
pstack->count--;
return pstack->values[pstack->count];
}
else
{
pstack->error = ERR_EMPTY;
return 0.0;
}
}
OPERATION Input(CALC_STACK* pstack)
{
char number[NUM_DIGITS + 1];
int cntnum = 0;
OPERATION ope = OPE_ENTER;
for (;;)
{
int ch = _getche();
if ('0' <= ch && ch <= '9' || ch == '.')
{
if (cntnum < NUM_DIGITS)
{
number[cntnum++] = (char)ch;
number[cntnum] = 0;
}
}
else{
if (ch == '+')
ope = OPE_PLUS;
else if (ch == '-')
ope = OPE_MINUS;
else if (ch == '*')
ope = OPE_MULTIPLY;
else if (ch == '/')
ope = OPE_DIVIDE;
else if (ch == '!')
ope = OPE_INVERSION;
else if (ch == 'c' || ch == 'C')
ope = OPE_CLEAR;
else if (ch == 'q' || ch == 'Q')
ope = OPE_EXIT;
break;
}
}
if (cntnum > 0)
Push(pstack, atof(number));
return ope;
}
void ShowCalculator( CALC_STACK stack)
{
int i;
printf("\n>>> RPN Calculator >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
printf("\n>>> +:加 -:減 *:乗 /:除 !:符号 c:削除 q:終了 >>>\n");
for (i = 0; i < stack.count; i++)
{
printf("%2d:%f\n", stack.count - i, stack.values[i]);
}
}
void main(void)
{
CALC_STACK stack;
stack.count = 0;
stack.error = ERR_NONE;
for (;;)
{
OPERATION operation;
ShowCalculator(stack);
operation = Input(&stack);
if (stack.error == ERR_OVERFLOW)
{
printf("\nOverflow!\n");
stack.error = ERR_NONE;
continue;
}
if (operation == OPE_INVERSION || operation == OPE_CLEAR){
if (stack.count < 1){
printf("\nError!\n");
}
else{
double n = Pop(&stack);
if (operation == OPE_INVERSION)
Push(&stack, n * (-1.0));
}
}
else if (operation == OPE_PLUS || operation == OPE_MINUS
|| operation == OPE_MULTIPLY || operation == OPE_DIVIDE)
{
if (stack.count < 2){
printf("\nError!\n");
}
else{
double n1 = Pop(&stack);
double n2 = Pop(&stack);
if (operation == OPE_PLUS)
Push(&stack, n1 + n2);
else if (operation == OPE_MINUS)
Push(&stack, n2 - n1);
else if (operation == OPE_MULTIPLY)
Push(&stack, n1 * n2);
else if (operation == OPE_DIVIDE)
{
if (n1 == 0.0)
printf("\nDivide by Zero!\n");
else
Push(&stack, n2 / n1);
}
}
}
else if (operation == OPE_EXIT)
{
break;
}
}
}