📄 cacluate.c
字号:
/************************************************/
/*软件名称:工程计算器1.0版 */
/*功能:可以计算数学表达式 */
/*作者:李士伟 */
/*编写时间: 2008.4 */
/*Email:cfixsoft@sina.com */
/************************************************/
/*************************** main.h ************************************/
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<String.h>
#include<conio.h>
#define EMPTY 0
#define FULL 100
#define N 4
#define M 13
typedef double data;
typedef enum{false,true} boolean;
int Cacluate(void);
void ShowHelp();
void ShowInfo();
/************************* end main.h **********************************/
/***************************datastk.h************************************/
struct elem
{
data d;
struct elem *next;
};
typedef struct elem elem;
struct DataStack
{
int cnt;/*记录元素个数*/
elem *top;
};
typedef struct DataStack DataStack;
/*********************** end datastk.h *************************************/
/********************************* optstack.h ******************************/
struct Operate
{
char opt;
struct Operate *next;
};
typedef struct Operate Operate;
struct OptStack
{
int cnt;/*记录元素个数*/
Operate *top;
};
typedef struct OptStack OptStack;
void OptStackPush(char opt,OptStack *ops);
int DealOpt(char opt,OptStack *ops,DataStack *ods);
void DealData(OptStack *ops,DataStack *ods);
char ChangeOpt(char *opts);
int OptCmp(char opt,char topopt);
/***************************** end optstack.h ******************************/
/****************************** datastk.c **********************************/
void DataStackPush(data d, DataStack *stk);
data DataStackPop(DataStack *stk);
void DataStackInit(DataStack *stk);
boolean DataStackEmpty(DataStack *stk);
boolean DataStackFull(DataStack *stk);
void DataStackPush(data d,DataStack *stk)
{
elem *pelem=(elem *)malloc(sizeof(elem));
if(pelem==NULL)
{
printf("Push DataStack error!");
exit(1);
}
pelem->d=d;
pelem->next=stk->top;
stk->top=pelem;
stk->cnt++;
}
data DataStackPop(DataStack *stk)
{
/*get DataStack top elem*/
data d;
elem *pelem;
d=stk->top->d; /* get top elem's data*/
pelem=stk->top;
stk->top=pelem->next; /* top point the next elem*/
stk->cnt--; /* DataStack's elem decrease 1 */
free(pelem); /* realse elemptr memory */
return(d);
}
void DataStackInit(DataStack *stk)
{
/* initialize DataStack,
set DataStack empty */
stk->cnt=EMPTY;
stk->top=NULL;
}
boolean DataStackEmpty(DataStack *stk)
{
/* test DataStack is empty*/
return((stk->cnt==EMPTY) ? true : false );
}
boolean DataStackFull(DataStack *stk)
{
/* test DataStack is full */
return((stk->cnt==FULL) ? true : false );
}
/******************************** end datastk.c ****************************/
/********************************* optstack.c ********************/
void OptStackInit(OptStack *stk)
{
/* initialize OptStack,
set OptStack empty */
stk->cnt=EMPTY;
stk->top=NULL;
}
boolean OptStackEmpty(OptStack *stk)
{
/* test OptStack is empty*/
return((stk->cnt==EMPTY) ? true : false );
}
boolean OptStackFull(OptStack *stk)
{
/* test DataStack is full */
return((stk->cnt==FULL) ? true : false );
}
void OptStackPush(char opt1,OptStack *ops)
{
Operate *optelem=(Operate *)malloc(sizeof(Operate));
if(optelem==NULL)
{
printf("Push OptStack error!");
exit(1);
}
ops->cnt++;
optelem->next=ops->top;
optelem->opt=opt1;
ops->top=optelem;
}
char OptStackPop(OptStack *ops)
{
Operate *optelem;
char op;
op=ops->top->opt;
optelem=ops->top;
ops->cnt--;
ops->top=optelem->next;
free(optelem);
return op;
}
char GetTopOpt(OptStack *ops)
{
return ops->top->opt;
}
/*********************************end optstack.c ********************/
/*********************************** main.c ******************************/
void main()
{
ShowInfo();
ShowHelp();
while((getch())!=23)
{
system("cls");
Cacluate();
}
getch();
}
void ShowInfo()
{
printf("\t\t\t************************");
printf("\n\t\t\t* 工程计算器1.0版 *");
printf("\n\t\t\t* 作者:Ricky *");
printf("\n\t\t\t* cfixsoft *");
printf("\n\t\t\t************************\n");
/* printf("\n\t\t\tF1------显示帮助\n");
printf("\n\t\t\tF2------保存计算记录\n");
*/
}
int Cacluate(void)
{
char str[100];
char *exper=str;
int i;
char opt;
char opts[6];
double a, t, b,doc;
DataStack ods; /*声明一个数据栈*/
OptStack ops; /*声明一个运算符栈*/
OptStackInit(&ops);
DataStackInit(&ods);
OptStackInit(&ops); /*初始化数据栈*/
DataStackInit(&ods); /*初始化运算符栈*/
do
{
system("cls");
printf("请输入计算表达式:");
gets(exper);
}
while(strlen(exper)==0);
while(*exper!='\0')
{
if(*exper>='0'&&*exper<='9'||*exper=='.')
{
a=0.0; t=10.0; b=1.0,doc=1;
while(*exper>='0'&&*exper<='9'||*exper=='.')
{
if(*exper>='0'&&*exper<='9')
a=a*t+(*exper-'0')*b;
b=b*doc;
if(*exper=='.')
{
doc=0.1;
b=0.1;
t=1.0;
}
exper++;
}
DataStackPush(a,&ods);
}
else if(*exper>='a'&&*exper<='z')
{
i=0;
while(*exper>='a'&&*exper<='z')
opts[i++]=*exper++;
opts[i]='\0';
opt=ChangeOpt(opts);
DealOpt(opt,&ops,&ods);
}
else if(*exper==',')
exper++;
else
{
DealOpt(*exper,&ops,&ods);
exper++;
}
}
while(OptStackEmpty(&ops)==false)
DealData(&ops,&ods);
messagebox("\n运算结果:%s=%0.6lf",str,ods.top->d);
return 0;
}
int DealOpt(char opt,OptStack *ops,DataStack *ods)
{
char topopt;
int a;
if(OptStackEmpty(ops)==false)
topopt=GetTopOpt(ops);
else
{
OptStackPush(opt,ops);
return 1;
}
a=OptCmp(opt,topopt);
if(a>=0||topopt=='(')
OptStackPush(opt,ops);
else
{
DealData(ops,ods);
DealOpt(opt,ops,ods);
}
return 1;
}
void DealData(OptStack *ops,DataStack *ods)
{
char opt;
data a,b;
switch(opt=OptStackPop(ops))
{
case '(':
OptStackPush(opt,ops);
break;
case ')':
while((opt=OptStackPop(ops))!='(')
{
OptStackPush(opt,ops);
DealData(ops,ods);
}
break;
case '+':
b=DataStackPop(ods);
a=DataStackPop(ods);
DataStackPush(a+b,ods);
break;
case '-':
b=DataStackPop(ods);
a=DataStackPop(ods);
DataStackPush(a-b,ods);
break;
case '*':
b=DataStackPop(ods);
a=DataStackPop(ods);
DataStackPush(a*b,ods);
break;
case '/':
b=DataStackPop(ods);
a=DataStackPop(ods);
DataStackPush(a/b,ods);
break;
case '!': /*sqrt()*/
a=DataStackPop(ods);
DataStackPush(sqrt(a),ods);
break;
case '#': /*cos()*/
a=DataStackPop(ods);
DataStackPush(cos(a),ods);
break;
case '$': /*sin()*/
a=DataStackPop(ods);
DataStackPush(sin(a),ods);
break;
case '?': /*ln()*/
a=DataStackPop(ods);
DataStackPush(log(a),ods);
break;
case '@': /*tan()*/
a=DataStackPop(ods);
DataStackPush(tan(a),ods);
break;
case ':': /*pow(a,b)*/
b=DataStackPop(ods);
a=DataStackPop(ods);
DataStackPush(pow(a,b),ods);
break;
case ';': /*exp()*/
a=DataStackPop(ods);
DataStackPush(exp(a),ods);
break;
case '&': /*acos()*/
a=DataStackPop(ods);
DataStackPush(acos(a),ods);
break;
case '_': /*asin()*/
a=DataStackPop(ods);
DataStackPush(asin(a),ods);
break;
case '~':/*atan()*/
a=DataStackPop(ods);
DataStackPush(atan(a),ods);
break;
case '^':
b=DataStackPop(ods);
a=DataStackPop(ods);
DataStackPush(log(a)/log(b),ods);
break;
case '>':
a=DataStackPop(ods);
DataStackPush(tan(a),ods);
break;
case '<': /*cot()*/
a=DataStackPop(ods);
DataStackPush(1.0/tan(a),ods);
break;
case '|': /*退出函数 */
exit(0);
}
}
int OptCmp(char opt1,char opt2)
{
/*比较运算符的优先级*/
int i, j, a, b;
char opttable[N][M]={{'+','-','\0','\0'},{'*','/','\0','\0'},{'<','>','&','!','#','?','$','@','~','_',':',';','^'},{'(',')','|','\0'}};
for(i=0;i<N;i++)
for(j=0;j<M;j++)
{
if(opt1==opttable[i][j]) a=i;
if(opt2==opttable[i][j]) b=i;
}
return a-b;
}
char ChangeOpt(char *opts)
{
/*用字符表示函数运算*/
int len1,len2;
int i, n, yes;
char optstr[]="sqrt!cos#sin$tan@pow:atan~asin_acos&ln?exp;log^tan>cot<exit|";
len1=strlen(opts);
len2=strlen(optstr);
for(i=0;i<len2;i++)
{
yes=1;
for(n=0;n<len1;n++)
if(opts[n]!=optstr[i+n]) yes=0;
if(yes==1)
break;
}
if(yes!=1)
exit(1); /*异常函数exit退出*/
else
return optstr[i+n]; /*正常函数返回*/
}
void ShowHelp()
{
/*一些引语*/
printf("=================================帮助==========================================\n");
printf("sqrt(x) 求x表达式的平方根.例如x为1.2+3.2时,求值的表达式:sqrt(1.2+3.2)\n");
printf("ln(x) 以e为底求x的对数.例如x为1.2+3.2时,求值的表达式:ln(1.2+3.2)\n");
printf("exp(x) 求e的x次方.例如x为1.2+3.2时,求值的表达式:exp(1.2+3.2)\n");
printf("pow(x,y) 求x的y次方.例如x为2,y为3时,求值的表达式:pow(2,3),结果:8\n");
printf("log(a,b) 以底为a,求b的对数.例如a为2,b为3时,求值的表达式:pow(2,3),结果:8\n");
printf("cos(x) 求x表达式的余弦值.例如x为1.2时,求值的表达式:cos(1.2)\n");
printf("sin(x) 求x表达式的正弦值.例如x为0.1+0.6时,求值的表达式:sin(0.1+0.6)\n");
printf("tan(x) 求x表达式的正切.例如x为0.8时,求值的表达式:tan(0.8)\n");
printf("cot(x) 求x表达式的余切.例如x为0.8时,求值的表达式:cot(0.8)\n");
printf("atan(x) 求x表达式的正切的反函数.例如x为0.8时,求值的表达式:atan(0.8)\n");
printf("acot(x) 求x表达式的余切的反函数.例如x为0.8时,求值的表达式:acot(0.8)\n");
printf("asin(x) 求x表达式的正弦的反函数.例如x为0.4时,求值的表达式:asin(0.4)\n");
printf("acos(x) 求x表达式的余弦的反函数.例如x为0.7时,求值的表达式:acos(0.7)\n");
printf("综合应用举例:ln(5)+1.2+3.2*(sin(3)/exp(2)+pow(2,3))\n");
printf("注意事项:所有的表达式要在英文状态下输入\n");
printf("输入exit正常退出。\n");
//printf("由于时间原因,小编目前只提供以上几种常用函数,敬请等待下个功能多的2.0版吧!\n");
//printf(" 感谢各位支持cfixsoft软件!\n\n");
}
/*********************************end main.c ***********************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -