📄 calculate.c
字号:
#include "calculate.h"
#include "stack.h"
int Calculate(char *s)
{
StackChar *OPTR;
StackDouble *OPND;
int BufferPointer=0;
int pointer = 0;
double FirstOut,SecondOut,TempResult,FinalResult;
char buffer[15];
char *endptr;
InitStackChar(&OPTR); //初始化操作数栈
PushChar(OPTR,'=');
InitStackDouble(&OPND); //初始化运算符栈
memset(buffer,'\0',sizeof(buffer));
strcat(s,"="); //先在输入的表达式后面加上等号
//printf("first\n");
while(*(s+pointer) != '\0')
{
if((*(s+pointer) >= '0')&&(*(s+pointer) <= '9')) //进行操作数的处理
{
if(JudgeChar(*(s+pointer+1))) //操作数的下一个字符是操作符,说明是小于10的数字,直接入栈
{
PushDouble(OPND,(*(s+pointer)-48));
//printf("%f\n",OPND->Top);
pointer++;
}
else
{
do
{
buffer[BufferPointer] = *(s+pointer);
BufferPointer++;pointer++;
}while(!JudgeChar(*(s+pointer))); //操作数的下一个字符还是数,先存入buffer
PushDouble(OPND,strtod(buffer,&endptr));
//puts(buffer);
//printf("%f\n",atof(buffer));
//printf("%lf\n",strtod(buffer,&endptr));
BufferPointer = 0; //清空buffer和BufferPointer
memset(buffer,'\0',sizeof(buffer)); //此处将buffer全置为'\0',置为NULL也行,不过会有一个警告
}
//printf("%lf\n",getTopdouble(OPND));
//printf("second\n");
}
if(JudgeChar(*(s+pointer))) //若输入为运算符+-*/()=
{
switch(precede(*(s+pointer),GetTopChar(OPTR)))
{
case '>': //操作符优先级高于栈顶元素,则操作符入栈
{
PushChar(OPTR,*(s+pointer));
pointer++;
//printf("%c\n",GetTopChar(OPTR));
//printf("third\n");
break;
}
case '<': //操作符优先级低于栈顶元素,操作数操作符出栈运算,并将运算结果入栈
{
FirstOut = PopDouble(OPND);
SecondOut = PopDouble(OPND);
if((GetTopChar(OPTR) == '/')&&(FirstOut == 0))
{
printf("除数不能为零!!\n");
return ERROR;
}
TempResult = operate(SecondOut,PopChar(OPTR),FirstOut);
//printf("TempResult = %f\n",TempResult);
PushDouble(OPND,TempResult);
break;
}
case '=': //脱括号
{
PopChar(OPTR);
pointer++;
break;
}
}
}
if((*(s+pointer) == '=')&&(GetTopChar(OPTR) == '=')) //表达式末尾的等号与栈内原有的等号相遇,说明操作符全部参与了运算,即计算完毕
{
FinalResult = PopDouble(OPND);
if(FinalResult >= 1e16) //10000000000000000
{
printf("超出表示范围!!\n");
return ERROR;
}
sprintf(buffer,"%5.10f",FinalResult);
printf("结果是:");
puts(buffer);
//FinalResult = TempResult;
//printf("FinalResult = %f\n",FinalResult);
break; //计算完毕应跳出循环
}
}
free(OPTR);
free(OPND); //free很重要!!
return !ERROR;
}
char precede(char a,char b) //优先级比较函数,同级运算符应返回小于号,加减乘除的优先级大于左右括号
{ //右括号优先级等于左括号,其余情况若出现则当作输入错误处理?
switch(a) //等号和等号相遇时应返回一个特殊值,而不是返回"="?
{
case '+':
switch(b)
{
case '+':return('<');
case '-':return('<');
case '*':return('<');
case '/':return('<');
case '(':return('>');
case ')':return('>');
case '=':return('>');
}
case '-':
switch(b)
{
case '+':return('<');
case '-':return('<');
case '*':return('<');
case '/':return('<');
case '(':return('>');
case ')':return('>');
case '=':return('>');
}
case '*':
switch(b)
{
case '+':return('>');
case '-':return('>');
case '*':return('<');
case '/':return('<');
case '(':return('>');
case ')':return('>');
case '=':return('>');
}
case '/':
switch(b)
{
case '+':return('>');
case '-':return('>');
case '*':return('<');
case '/':return('<');
case '(':return('>');
case ')':return('>');
case '=':return('>');
}
case '(':
switch(b)
{
case '+':return('>');
case '-':return('>');
case '*':return('>');
case '/':return('>');
case '(':return('>');
case ')':return('=');
case '=':return('>');}
case ')':
switch(b)
{
case '+':return('<');
case '-':return('<');
case '*':return('<');
case '/':return('<');
case '(':return('=');
case ')':return('>');
case '=':return('>');}
case '=':
switch(b)
{
case '+':return('<');
case '-':return('<');
case '*':return('<');
case '/':return('<');
case '(':return('<');
case ')':return('F');/*返回错误*/
case '=':return('F');}
} /*switch(a)*/
}
double operate(double a,char theta,double b) //元素运算函数
{
switch(theta)
{
case '+':return(a+b);
case '-':return(a-b);
case '*':return(a*b);
case '/':return(a*1.0/b);
}
}
//判断字符'a'是否为"+-*/()="的其中之一
int JudgeChar(char a)
{
switch(a)
{
case '+':return 1;
case '-':return 1;
case '*':return 1;
case '/':return 1;
case '(':return 1;
case ')':return 1;
case '=':return 1;
default: return 0;
}
}
//判断是否为"+-*/"的其中之一
int JudgeOptrChar(char a)
{
switch(a)
{
case '+':return 1;
case '-':return 1;
case '*':return 1;
case '/':return 1;
default: return 0;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -