该楼层疑似违规已被系统折叠隐藏此楼查看此楼
#include
#include
#include
struct Numerical
{
double value;
struct Numerical *next;
};
struct Symbol
{
char c;
struct Symbol *next;
};
void Push_Numerical(struct Numerical **top,double value)
{
struct Numerical *p = *top;
(*top = (struct Numerical*)malloc(sizeof (struct Numerical)))->next = p;
(*top)->value = value;
}
void Push_Symbol(struct Symbol **top,char c)
{
struct Symbol *p = *top;
(*top = (struct Symbol*)malloc(sizeof (struct Symbol)))->next = p;
(*top)->c = c;
}
double Pop_Numerical(struct Numerical **top)
{
struct Numerical *p = *top;
double n = (*top)->value;
*top = (*top)->next;
free(p);
return n;
}
char Pop_Symbol(struct Symbol **top)
{
struct Symbol *p = *top;
char c = (*top)->c;
*top = (*top)->next;
free(p);
return c;
}
int priority(char c)
{
switch (c)
{
case *+*:
case *-*:
return 1;
case ***:
case */*:
return 2;
default:
return 10;
}
}
double calculate(char c,double l,double g)
{
switch (c)
{
case *+*:
return l + g;
case *-*:
return l - g;
case ***:
return l * g;
case */*:
return l / g;
}
}
int main (void)
{
struct Numerical *Numerical_stack = NULL;
struct Symbol *Symbol_stack = NULL;
double n;
int last_number = 0; //上一个读取的是不是数则值为假,如果上一个读取的是数,下一个只能是读取字符
char pop_c,c;
puts("表达式计算器\n\n");
puts("1.作者很笨,写出来的程序智商很低,因此它是一个很单纯的计算器,请不要用复杂的算数表达式为难它\n");
puts("2.因为作者忘记了除数不能为0,所以并没有做特殊处理,请不要故意除以0\n");
puts("3.当你输入错误的表达式,程序会采用崩溃的方式提示你的输入有误,请重启程序重新输入\n");
puts("4.支持的运算符:英文状态下:‘(’‘)’‘+’‘-’‘*’‘/’\n");
puts("程序有些BUG,某些表达式会得出错误的结果,希望大家能够指出\n作者:642985327");
system("pause");
system("cls");
begin:
if((c = getchar()) == *-*)Push_Numerical(&Numerical_stack,0); //如:-(5)第一个字符被压栈双目运算数字栈空导致错误
ungetc(c,stdin);
while ((c = getchar())!= *\n*) //读取表达式内容,在转换后缀表达式的同时进行运算
{
ungetc(c,stdin);
if (last_number == 0 && scanf("%lf",&n))
{
Push_Numerical(&Numerical_stack,n);
last_number = 1;
}
else
{
char a = getchar();
if ((c == *+* || c == *-* ) && c != a && last_number != 1) //防止scanf吃掉正负号导致程序错误计算,如果scanf勿吃掉了计算用的正负号则仍回输入流
ungetc(a,stdin);
else
c=a;
if ((c) == *)*)
{
while ((pop_c = Pop_Symbol(&Symbol_stack)) != *(*)
{
double g = Pop_Numerical(&Numerical_stack);
double l = Pop_Numerical(&Numerical_stack);
Push_Numerical(&Numerical_stack,calculate(pop_c,l,g));
}
}
else if (Symbol_stack == NULL || c == *(* || Symbol_stack->c ==*(* || priority(Symbol_stack->c) < priority(c))
{
Push_Symbol(&Symbol_stack,c);
}
else
{
while (Symbol_stack->c != *(*)
{
pop_c = Pop_Symbol(&Symbol_stack);
double g = Pop_Numerical(&Numerical_stack);
double l = Pop_Numerical(&Numerical_stack);
Push_Numerical(&Numerical_stack,calculate(pop_c,l,g));
if (Symbol_stack == NULL || priority(Symbol_stack->c) < pop_c || Symbol_stack->c == *(*)break;
}
Push_Symbol(&Symbol_stack,c);
}
if (c != *)*)last_number = 0; //除了在读到*)*的情况,读到其他符号,下一次都能尝试读取一个数字
}
}
while (Symbol_stack != NULL) //剩余符号全部弹出栈参与运算
{
double g = Pop_Numerical(&Numerical_stack);
double l = Pop_Numerical(&Numerical_stack);
Push_Numerical(&Numerical_stack,calculate(Pop_Symbol(&Symbol_stack),l,g));
}
printf("%g\n",Pop_Numerical(&Numerical_stack));
goto begin
return 0;
}