#pragma once
#include <stdio.h>
#include <math.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#define PI (3.14159265358979323846/180.0) //改为角度输入
#define EPS (1e-7) //浮点数比较
#define N 8 //函数名称字符的最大长度
//#define M 7 //现支持函数个数
#define MAX_INFIX 128 //表达式的最大长度
double EvExpre(void); //表达式求值函数
int calcMain( void )
{
while(8)
{
printf("\n请输入计算表达式:");
rewind(stdin);
printf("表达式值为:%.13lg\r",EvExpre());
}
return 0;
}
static double ftoa_zw(char *c) //字符转实数
{
double n=0.0;
if(isdigit(*c))
do
{
n=n*10.0+(*c-'0');
}
while(isdigit(*c=getchar()));
if(*c=='.')
{
double m=1.0;
while(isdigit(*c=getchar()))
{
n=n*10.0+(*c-'0');
m*=10.0;
}
n /= m;
}
return n;
}
static int isfunc(const char *cur)//是否是函数符(是返回下标,否返-1)
{
const char *ap[]= {"sin","asin","cos","acos","tan","exp","log",NULL};
const char **i;
for(i=ap;*i!=NULL; ++i)
if(strcmp(*i,cur)==0)
return (int)(i-ap);
return -1;
}
static double mathfuc(double n,int i)//函数运算
{
double (*f[])(double)= {sin,asin,cos,acos,tan,exp,log,NULL};//一一对应
if(i<0 || i>= sizeof(f)/sizeof(f[0])-1 )
{
puts("程序异常退出...");
exit(-1);
}
if(i<5) n *= PI;
return f[i](n);
}
static int func(double *op,int *j,char *c)//函数判定、求值或进符号栈
{
char temp[N+1]= {0};
int i=0;
do
{
temp[i++]=*c;
}
while(islower(*c=getchar()) && i < N );
if((i=isfunc(temp))!=-1)//如果是函数符
{
if(*c=='(') //直接入符号栈 sin(30+60)
return ('0'+i); //函数代码入数字栈
//return i;
int sig=1;
if(*c=='-' || *c=='+')
{
if(*c=='-') sig=-1;
*c=getchar();
}
if(isdigit(*c) || *c=='.')
{
*(op+1)=mathfuc(sig*ftoa_zw(c),i); //计算结果入数字栈 sin30
*j += 1;
return 0; //成功返0
//return -2 //成功返-2
}
}
if(*c=='\n') puts("语法错误..."); // sin
return -1;
}
static int isoper(const char oper)//是否运算符
{
const char *p="+-*/^!F";
for(; *p && *p!=oper; ++p);
return *p ? 1 : 0;
}
static double fanc(double n)//阶乘函数(171以内)
{
if(n<-EPS)
{
puts("对负数阶乘无效...");
return 0.0;
}
int i,t;
double num=1.0;
for(t=(int)n,i=1; i<=t; ++i)
num*=i;
return num;
}
static int precede(char top,char cur)/*判定优先级函数*/
{
char ch='>';//默认栈顶优先级高
switch(cur)
{
case '+':
case '-':
if(top=='(' || top=='\n')
ch='<';
break;
case '*':
case '/':
if(top=='+' || top=='-' ||top=='(' || top=='\n')
ch='<';
break;
case '(':
ch='<';
break;
case ')':
if(top=='(')
ch='=';
break;
case '\n':
if(top=='\n')
ch='=';
if(top=='(') ch=-1;
break;
case '^':
if(top!='!'&&top!='F')
ch='<';
break;
case '!':
if(top!='^'&&top!='F')
ch='<';
break;
case 'F':
if(top!='^'&&top!='!')
ch='<';
break;
default:
ch=-1;
break;
}
return ch;
}
static int operate(double *op,int *i,char oper)//二元运算(利于阶乘)
{
if(oper!='!'&&*i==0)
{
puts("语法错误...");
return 0;
}
*i-=1;
switch(oper)
{
case '+':
*(op-1)+=*op;
break;
case '-':
*(op-1)-=*op; //注意顺序
break;
case '*':
*(op-1)*=*op;
break;
case '/':
if(*op==0)
{
fprintf(stderr,"错误:除数为零\n");
return 0;
}
*(op-1)/=*op;
break;
case '^':
*(op-1)=pow(*(op-1),*op);
break;
case '!':
*i+=1;
*op=fanc(*op);
break;
case 'F':
*(op-1)=mathfuc(*op,(int)(*(op-1)));
break;
}
return 1;
}
double EvExpre(void) //中缀表达式求值函数
{
char c;
register int sig=1; //正负数判断
int i=-1; //数字栈的栈顶指针
register int j=0; //符号栈的栈顶指针
double OP[MAX_INFIX/2]= {0.0}; //数字栈
char OPER[MAX_INFIX/2]= {'\n'}; //符号栈
c=getchar();
while(c!='\n' || OPER[j]!='\n')
{
if(i==-1 && (c=='-'||c=='+')) //负数
{
sig=(c=='-')?-1:1;
c=getchar();
}
if(isdigit(c)||c=='.')
{
OP[++i]=ftoa_zw(&c)*sig;
sig=1;
}
if(islower(c))
{
int n;
if((n=func(&OP[i],&i,&c))==-1)//语法错误
return 0.0;
if(n) //if(n!=-2)
{
OPER[++j]='F'; //'F'代表是函数符
OP[++i]=(double)(n-'0');//函数符代码入数字栈
//OP[++i]=(double)n;
}
}
switch(precede(OPER[j],c))
{
case '<':
OPER[++j]=c;
if((c=getchar())=='-'||c=='+')
{
sig=(c=='-')?-1:1;
c=getchar();
}
break;
case '=':
if(j>0)
{
--j;
c=getchar();
}
break;
case '>':
if(isoper(OPER[j]))
if(!operate(&OP[i],&i,OPER[j--])) return 0.0;
break;
default:
puts("语法错误...");
return 0.0;
}
}
return OP[i];
}
console calc 控制台 计算器
最新推荐文章于 2023-05-21 12:25:54 发布