我是打算编一下简易计算器,C语言还是刚学的,只是想练一下刚学的知识,算法可能不太好,高手们可别笑话我这菜鸟哈!
程序很长麻烦耐心帮忙看看,有啥错误或能改进的请多多指教!!!!
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<ctype.h>
#include<math.h>
char operator_str[]={'+','_','*','/','^','@','!','s','c','t','S','C','T'};
/*存放合法符号,便于比较*/
char input[256];
/*储存用户输入的算式*/
double result=0.0;
short *right=NULL,*left=NULL,YN=1; /*指针记录左右括号的位置*/
unsigned short i=0,j=0 ,k=0,count=0;
struct char_double
{
char Operator;
double num;
};
typedef struct char_double mytype;
mytype dealing[256];
double Caculater(struct char_double,short*,short*);
long fact(long);
void main()
{
printf("计算器说明:"
"\n\t1.该计算器支持+、-、*、/、^、!、@等基本运算;"
"\n\t2.适当时候可以使用()来帮助表达,算式输完按ENTER键即可;"
"\n\t3.\"^\"表示指数运算;\"s,c,t\"分别表示正弦、余弦、正切;"
"\n\t
大写(S、C、T)表示相应的反三角函数;\"!\"表示阶乘运算;\"a@b\"表示以a为底的b的对数."
" \n 请输入计算式:");
wrong:
while(strcmp(gets(input),"quit")!=0)
{
/*对用户输入的算式进行格式化处理*/
for(i=0,count=0;i<strlen(input);i++)
if(strchr(operator_str,input[i])!=NULL)
{
if(YN==0) YN=1;
count++;
}
else if((isdigit(input[i]))&&YN) count++;
count++;
for(i=0,j=1,YN=1;i<strlen(input);i++)
/*第一个位置预留,便于使用前次结果参与计算时存放前次运算结果*/
if(strchr(operator_str,input[i])!=NULL)
{
if(YN==0) YN=1;
dealing[j++].Operator=input[i];
}
else if((isdigit(input[i]))&&YN)
{
dealing[j++].num=atof(input+i);
YN=0;
}
/*以上步骤得到了double型数字和运算符组成的数据
···················
分析第一个字符是否是=号*/
if(dealing[1].Operator!='\0') dealing[0].num=result;
else dealing[0].Operator='$';
/*$表示失效数据*/
/*对算式中的括号进行由里到外,从左到右的处理*/
int number1=0,number2=0;
do
{
for(i=1;i<count;i++)
{
if(dealing[i].Operator=='(') ++number1;
/*得到算式中括号的个数*/
else if(dealing[i].Operator==')') ++number2;
}
if(number1!=number2)
{
printf("
算式不合法,括号使用不正确!\n\t请重新输入:");
goto wrong;
}
if(number1!=0)
{
right=(short*)malloc(number1);
left=(short*)malloc(number2);
for(k=1,i=0,j=0;k<count;k++) /*找到括号的确切位置*/
{
if(dealing[k].Operator=='(') *(left+i++)=k;
else if(dealing[k].Operator==')') *(right+j++)=k;
}
/*处理的目标括号为第一个“)”(即*right)和其左边出现的最后一个“(”(即下面得到的*(left+k-1))组成的括号*/
for(k=0;k<number1;k++) if(*(left+k)>*right) break;
left=left+k-1;
/*对()的运算式进行处理*/
result=Caculater(dealing[256],right,left);
/*通过调用计算函数赋给result*/
/*更新pm,为再次进行去括号做好准备*/
dealing[*left].num=result;
for(i=*left+1;i<*right+1;i++) dealing[i].Operator='$';
}
}while(number1);
/*经过do-while循环最终得到一个没有括号的计算式,最后一次调用Caculator的到最终结果*/
result=Caculater(dealing[256],dealing,&dealing[count].Operator);
/*最后一次调用时处理对象为整个输入计算式长度*/
/* printf("=%f\n
请再次输入计算式(运算式以运算符开始表示利用上次结果):",result);*/
printf("=%.4f.\n\t请输入计算式:",result);
}
}
double Caculater(mytype dealing[],short *right,short *left)
{
short big=*right,little=*left,i=0,j=0;
char letters[]={'!','^','@','s','c','t','S','C','T'};
/*存放运算符,便于比较*/
double math1=0.0,math2=0.0;
for(i=little+1;i<big;i++)
/*处理优先级较高的运算符*/
if(strchr(letters,dealing[i].Operator)!=NULL)
{
switch(dealing[i].Operator)
{
case '!':
for(j=i-1;j>little;j--)
if(dealing[j].Operator=='\0') /*dealing[j].Operator='\0'(默认初始值为'\0')时说明dealing[i].num有效*/
{
dealing[j].num=(double)fact((long)dealing[i].num); /*运算结果储存在本次运算的运算数的dealing[i].num里*/
break;
}
case '^':
{
for(j=i-1;j>little;j--)
if(dealing[j].Operator=='\0')
{
math1=dealing[j].num;
dealing[j].Operator='$';
/*处理过的数据标记为无效*/
break;
}
for(j=i+1;j<big;j++)
if(dealing[j].Operator=='\0')
{
math2=dealing[j].num;
break;
}
dealing[j].num=pow(math1,math2);
math1=0.0;
math2=0.0;
}
case '@':
{
for(j=i-1;j>little;j--)
if(dealing[j].Operator=='\0')
{
math1=dealing[j].num;
dealing[j].Operator='$';
break;
}
for(j=i+1;j<big;j++)
if(dealing[j].Operator=='\0')
{
math2=dealing[j].num;
break;
}
dealing[j].num=log(math2)/log(math1);
math1=0.0;
math2=0.0;
}
case 's':
for(j=i+1;j<big;j++)
if(dealing[j].Operator=='\0')
{
dealing[j].num=sin(dealing[i].num*3.141592/180.0);
break;
}
case 'c':
for(j=i+1;j<big;j++)
if(dealing[j].Operator=='\0')
{
dealing[j].num=cos(dealing[i].num*3.141592/180.0);
break;
}
case 't':
for(j=i+1;j<big;j++)
if(dealing[j].Operator=='\0')
{
dealing[j].num=tan(dealing[i].num*3.141592/180.0);
break;
}
case 'S':
for(j=i+1;j<big;j++)
if(dealing[j].Operator=='\0')
{
dealing[j].num=asin(dealing[i].num*3.141592/180.0);
break;
}
case 'C':
for(j=i+1;j<big;j++)
if(dealing[j].Operator=='\0')
{
dealing[j].num=acos(dealing[i].num*3.141592/180.0);
break;
}
case 'T':
for(j=i+1;j<big;j++)
if(dealing[j].Operator=='\0')
{
dealing[j].num=atan(dealing[i].num*3.141592/180.0);
break;
}
dealing[i].Operator='$';
}
}
for(i=little+1;i<big;i++)
/*乘除运算*/
{
if(dealing[i].Operator=='*')
{
for(j=i-1;j>little;j--)
if(dealing[j].Operator=='\0')
{
math1=dealing[j].num;
dealing[j].Operator='$';
break;
}
for(j=i+1;j<big;j++)
if(dealing[j].Operator=='\0')
{
math2=dealing[j].num;
break;
}
dealing[j].num=math1*math2;
dealing[i].Operator='$';
}
if(dealing[i].Operator=='/')
{
for(j=i-1;j>little;j--)
if(dealing[j].Operator=='\0')
{
math1=dealing[j].num;
dealing[j].Operator='$';
break;
}
for(j=i+1;j<big;j++)
if(dealing[j].Operator=='\0')
{
math2=dealing[j].num;
break;
}
dealing[j].num=math1/math2;
dealing[i].Operator='$';
math1=0.0;
math2=0.0;
}
}
for(i=little+1,j=0;i<big;i++)
/*处理加减运算*/
{
if(dealing[j].Operator=='+')
{
for(j=i-1;j>little;j--)
if(dealing[j].Operator=='\0')
{
math1=dealing[j].num;
dealing[j].Operator='$';
break;
}
for(j=i+1;j<big;j++)
if(dealing[j].Operator=='\0')
{
math2=dealing[j].num;
break;
}
dealing[j].num=math1+math2;
dealing[i].Operator='$';
math1=0.0;
math2=0.0;
}
if(dealing[i].Operator=='-')
{
for(j=i-1;j>little;j--)
if(dealing[j].Operator=='\0')
{
math1=dealing[j].num;
dealing[j].Operator='$';
break;
}
for(j=i+1;j<big;j++)
if(dealing[j].Operator=='\0')
{
math2=dealing[j].num;
break;
}
dealing[j].num=math1-math2;
dealing[i].Operator='$';
}
}
return
dealing[j].num; /*最后一次进行的加\减运算结果即运算结果*/
}
long fact(long N)
/*阶乘函数*/
{
long i=0,total=0;
for(i=N;i>0;)
total=total*i--;
return total;
}