下面这个程序支持加+ 减- 乘* 除/ 阶乘! 开方? 平方^ 取模% 等运算 支持括号和括号内优先级 可以输入负数 不过输入负数时需要用括号括上 这个程序 一定有不少 缺点 我也没有用一些表达式 进行运算验证 这个验证的过程就交给大家把 如果各位发现输入的表达式 计算错误的话 请将表达式和结果 发到帖子上来 我会修改的 如果哪位有兴致的话 可以将一些不完善的功能 修改也发到帖子上来 供大家共同学习进步 #include<math.h>
#include<ctype.h>
#include<stdio.h>
typedef struct list
{
double data;
struct list *next;
}NODE;
typedef NODE *LLIST;
LLIST operater=NULL;
LLIST number=NULL;
LLIST oper=NULL;
LLIST ber=NULL;
int empty(LLIST operater)
{
if(operater==NULL)return 1;
else return 0;
}
LLIST stackin(LLIST operater,double b)
{
LLIST ptr;
ptr=(LLIST)malloc(sizeof(NODE));
ptr->data=b;
ptr->next=operater;
operater=ptr;
return operater;
}
LLIST stackout(LLIST number,double *num)
{
LLIST ptr=number;
if(number!=NULL)
{
number=number->next;
*num=ptr->data;
free(ptr);
return number;
}
}
int max(char sum)
{
switch(sum)
{
case '+':
case '-':return 2;
case '*':
case '%':
case '/':return 3;
case '(':
case ')':return 1;
case '!':return 4;
case '^':return 5;
case '?':return 4;
default:return 0;
}
}
double tatal(double num1,double num2,char sum)
{
int i;
double s;
switch(sum)
{
case '+':return(num2+num1);
case '-':return(num2-num1);
case '*':return(num2*num1);
case '/':return(num2/num1);
case '%':return((int)num2%(int)num1);
case '!':return Stairs((int)num2);
case '?':return sqrt(num2); /* 开方 and !和?同时出现*/
case '^':for(i=0;i<num1;i++)
if(i==0)s=num2;
else s*=num2;
return s;
}
}
Contrary(double num1,double num2,char sum)
{
double s;
int i;
switch(sum)
{
case '-':return(num1-num2);
case '/':return(num1/num2);
case '%':return((int)num1%(int)num2);
case '^':for(i=0;i<num2;i++)
if(i==0)s=num1;
else s*=num1;
return s;
}
}
Stairs(int num2)
{
if(num2<=1)return 1;
else return num2*Stairs(num2-1);
}
outdata(LLIST operater)
{
LLIST ber=operater;
while(ber!=NULL)
{
printf("%lf ",ber->data);
ber=ber->next;
}
printf("\n");
}
outoper(LLIST operater)
{
LLIST oper=operater;
while(oper!=NULL)
{
printf("%c",oper->data);
oper=oper->next;
}
printf("\n");
}
char *filter(char *c)
{
int j=0,i=0;
char *s;
while(c[i]!='\0'&&c[i]!='\n')
{
if(c[i]!=' '&&max(c[i])||isdigit(c[i])||c[i]=='.')
{
if(c[i]=='!'||c[i]=='?'){ if(isdigit(c[i-1])||c[i-1]==')')s[j++]=c[i]; }
else if(c[i]=='.'){ if(isdigit(c[i-1]))s[j++]=c[i]; }
else s[j++]=c[i];
}
i++;
}
s[j]='\0';
return s;
}
Resolve(char *s,double *a,char *t)
{
int k=1,i=0,l=0;
while(s[i]!='\0'&&s[i]!='\n')
{
char p[50]={0}; int j=0;
if(max(s[i])){ if(s[i]=='('&&s[i+1]=='-')
{
i+=2;
while(isdigit(s[i])||s[i]=='.')p[j++]=s[i++];
a[k++]=0-atof(p);
i++;
}
else t[l++]=s[i++];
}
else {
while(isdigit(s[i])||s[i]=='.')p[j++]=s[i++];
a[k++]=atof(p);
}
}
t[l]='\0';
a[0]=k-1; }
main()
{
double k,j=0,i=0,a[50];
double num,num1,num2,sum,kern=1;
char b[50],c[100],*s;
printf("please input Express type: ");
gets(c);
s=filter(c);
Resolve(s,a,b);
while(b[i]!='\0'&&b!='\n')
{
if(b[i]!='('){ if(kern<=a[0])number=stackin(number,a[kern++]); }
jump:if(b[i]=='!'||b[i]=='?'){ number=stackout(number,&num); number=stackin(number,tatal(0,num,b[i])); }
else if(operater==NULL||b[i]=='(')operater=stackin(operater,(double)b[i]);
else if(b[i]==')')
{
if((char)operater->data=='(')operater=stackout(operater,&sum);
else { while((char)operater->data!='(')
{
number=stackout(number,&num);
ber=stackin(ber,num);
operater=stackout(operater,&sum);
if(oper==NULL)oper=stackin(oper,sum);
else {
if(max((char)sum)<=max((char)oper->data)&&ber->next!=NULL)
{
ber=stackout(ber,&num1);
ber=stackout(ber,&num2);
oper=stackout(oper,&num);
ber=stackin(ber,tatal(num1,num2,(char)num));
}
oper=stackin(oper,sum);
}
}
number=stackout(number,&num1);
ber=stackin(ber,num1);
operater=stackout(operater,&sum);
ber=stackout(ber,&num1);
ber=stackout(ber,&num2);
oper=stackout(oper,&num);
if((char)num=='-'||(char)num=='/'||(char)num=='%'||(char)num=='^')number=stackin(number,Contrary(num1,num2,(char)num));
else { number=stackin(number,tatal(num1,num2,(char)num)); /* i++; goto jump; */}
}
}
else {
if(max(b[i])<=max((char)operater->data)&&number->next!=NULL)
{
number=stackout(number,&num1);
number=stackout(number,&num2);
operater=stackout(operater,&sum);
num=tatal(num1,num2,(char)sum);
number=stackin(number,num);
}
operater=stackin(operater,(double)b[i]);
}
i++;
}
if(kern<=a[0])number=stackin(number,a[kern]);
while(operater!=NULL)
{
number=stackout(number,&num1);
number=stackout(number,&num2);
operater=stackout(operater,&sum);
number=stackin(number,tatal(num1,num2,(char)sum));
}
for(k=0;s[k]!='\0';k++)printf("%c",s[k]);
number=stackout(number,&num2);
printf("=%lf\n",num2);
printf("\nCalculation End! Thank you!\n");
getch();
}
阶乘! 和开方? 运算符 要放在操作数的右边 大家给点意见把 看看这个程序还有什么地方可以进行改进的地方
[此贴子已经被作者于2004-07-10 13:24:09编辑过]
----------------解决方案--------------------------------------------------------
奇怪了 前几天在我朋友那台windows me 上怎么运行不了?
各位朋友 这个程序 能运行么? 不好使的话 回帖 告诉我一声
----------------解决方案--------------------------------------------------------
我在TC2.0编译器(xp操作)
中编译,有27个警告
7个错误啊
----------------解决方案--------------------------------------------------------
真晕 早知道就不做修改了 改了一个地方 现在是真不能运行了
最近忙于奔波 没时间调试程序了 等我有时间再重新做一次把 见谅了各位
----------------解决方案--------------------------------------------------------
经过修改 现在这个程序终于可以成功运行了 一楼的程序是文本模式的 可以正常运行 出现的问题不大 下面的这个是图形模式下的 由于使用了 循环所以有的时候运算的结果不是很准确 只要把mian函数里的循环拿掉就可以正常运算了
#include<math.h>
#include<graphics.h>
#include<ctype.h>
#include<stdio.h>
typedef struct list
{
double data;
struct list *next;
}NODE;
typedef NODE *LLIST;
LLIST operater=NULL;
LLIST number=NULL;
LLIST oper=NULL;
LLIST ber=NULL;
int empty(LLIST operater)
{
if(operater==NULL)return 1;
else return 0;
}
LLIST stackin(LLIST operater,double b)
{
LLIST ptr;
ptr=(LLIST)malloc(sizeof(NODE));
ptr->data=b;
ptr->next=operater;
operater=ptr;
return operater;
}
LLIST stackout(LLIST number,double *num)
{
LLIST ptr=number;
if(number!=NULL)
{
number=number->next;
*num=ptr->data;
free(ptr);
return number;
}
}
int max(char sum)
{
switch(sum)
{
case '+':
case '-':return 2;
case '*':
case '%':
case '/':return 3;
case '(':
case ')':return 1;
case '!':return 4;
case '^':return 5;
case '?':return 4;
default:return 0;
}
}
double tatal(double num1,double num2,char sum)
{
int i;
double s;
switch(sum)
{
case '+':return(num2+num1);
case '-':return(num2-num1);
case '*':return(num2*num1);
case '/':return(num2/num1);
case '%':return((int)num2%(int)num1);
case '!':return Stairs((int)num2);
case '?':return sqrt(num2);
case '^':for(i=0;i<num1;i++)
if(i==0)s=num2;
else s*=num2;
return s;
}
}
Contrary(double num1,double num2,char sum)
{
double s;
int i;
switch(sum)
{
case '-':return(num1-num2);
case '/':return(num1/num2);
case '%':return((int)num1%(int)num2);
case '^':for(i=0;i<num2;i++)
if(i==0)s=num1;
else s*=num1;
return s;
}
}
Stairs(int num2)
{
if(num2<=1)return 1;
else return num2*Stairs(num2-1);
}
outdata(LLIST operater)
{
LLIST ber=operater;
while(ber!=NULL)
{
printf("%lf ",ber->data);
ber=ber->next;
}
printf("\n");
}
outoper(LLIST operater)
{
LLIST oper=operater;
while(oper!=NULL)
{
printf("%c",oper->data);
oper=oper->next;
}
printf("\n");
}
char *filter(char *c)
{
int j=0,i=0;
char *s;
while(c[i]!='\0'&&c[i]!='\n')
{
if(c[i]!=' '&&max(c[i])||isdigit(c[i])||c[i]=='.')
{
if(c[i]=='!'||c[i]=='?'){ if(isdigit(c[i-1])||c[i-1]==')')s[j++]=c[i]; }
else if(c[i]=='.'){ if(isdigit(c[i-1]))s[j++]=c[i]; }
else s[j++]=c[i];
}
i++;
}
s[j]='\0';
return s;
}
Resolve(char *s,double *a,char *t)
{
int k=1,i=0,l=0;
while(s[i]!='\0'&&s[i]!='\n')
{
char p[50]={0}; int j=0;
if(max(s[i])){ if(s[i]=='('&&s[i+1]=='-')
{
i+=2;
while(isdigit(s[i])||s[i]=='.')p[j++]=s[i++];
a[k++]=0-atof(p);
i++;
}
else t[l++]=s[i++];
}
else {
while(isdigit(s[i])||s[i]=='.')p[j++]=s[i++];
a[k++]=atof(p);
}
}
t[l]='\0';
a[0]=k-1; }
Calculation()
{
int x,n=0,j=0,i=0,kern=1;
char b[20],c[20],*s;
double a[20];
double num,num1,num2,sum;
cleardevice();
setcolor(BLUE);
outtextxy(200,200,"please input Express type: ");
setcolor(WHITE);
rectangle(160,235,440,260);
gotoxy(22,16);
while((c[n++]=getch())!=13)
if(c[n-1]==8){ if(n==1)n--; else { gotoxy(wherex()-1,16); printf(" "); n--; printf("%c",c[n]); n--; } }
else printf("%c",c[n-1]);
s=filter(c);
Resolve(s,a,b);
while(b[i]!='\0'&&b!='\n')
{
if(b[i]!='('){ if(kern<=a[0])number=stackin(number,a[kern++]); }
if(b[i]=='!'||b[i]=='?'){ number=stackout(number,&num); number=stackin(number,tatal(0,num,b[i])); }
else if(operater==NULL||b[i]=='(')operater=stackin(operater,(double)b[i]);
else if(b[i]==')')
{
if((char)operater->data=='(')operater=stackout(operater,&sum);
else { while((char)operater->data!='(')
{
number=stackout(number,&num);
ber=stackin(ber,num);
operater=stackout(operater,&sum);
if(oper==NULL)oper=stackin(oper,sum);
else {
if(max((char)sum)<=max((char)oper->data)&&ber->next!=NULL)
{
ber=stackout(ber,&num1);
ber=stackout(ber,&num2);
oper=stackout(oper,&num);
ber=stackin(ber,tatal(num1,num2,(char)num));
}
oper=stackin(oper,sum);
}
}
number=stackout(number,&num1);
ber=stackin(ber,num1);
operater=stackout(operater,&sum);
ber=stackout(ber,&num1);
ber=stackout(ber,&num2);
oper=stackout(oper,&num);
if((char)num=='-'||(char)num=='/'||(char)num=='%'||(char)num=='^')number=stackin(number,Contrary(num1,num2,(char)num));
else { number=stackin(number,tatal(num1,num2,(char)num)); }
}
}
else {
if(max(b[i])<=max((char)operater->data)&&number->next!=NULL)
{
number=stackout(number,&num1);
number=stackout(number,&num2);
operater=stackout(operater,&sum);
num=tatal(num1,num2,(char)sum);
number=stackin(number,num);
}
operater=stackin(operater,(double)b[i]);
}
i++;
}
if(kern<=a[0])number=stackin(number,a[kern]);
while(operater!=NULL)
{
number=stackout(number,&num1);
number=stackout(number,&num2);
operater=stackout(operater,&sum);
number=stackin(number,tatal(num1,num2,(char)sum));
}
number=stackout(number,&num2);
printf("=%lf\n",num2);
outtextxy(180,300,"\nCalculation End! Thank you!\n");
}
main()
{
int gd=DETECT,gm=0;
char key=1;
registerbgidriver(EGAVGA_driver);
initgraph(&gd,&gm,"");
while(key!=27)
{
Calculation();
key=getch();
key=getch();
}
closegraph();
}
----------------解决方案--------------------------------------------------------
受到mikewolf的启发 发现这个计算器的阶乘功能并没有对超出范围进行解决 与是修改了一下计算阶乘的代码
感谢mikewolf的帮助
Stairs(int num2)
{
unsigned int *s;
int i;
if(num2<8)return stairs2(num2);
s=(unsigned int *)malloc(num2*sizeof(s));
for(i=1;i<num2;i++)s[i]=0;
s[0]=1;
for(i=2;i<=num2;i++)mystairs(s,i);
i=--num2;
while(!s[i])i--;
printf("=%d",s[i--]);
for(;i>=0;i--)printf("%04d",s[i]);
getch(); return 0;
}
stairs2(num2)
{
if(num2<=1)return 1;
else return num2*stairs2(num2-1);
}
mystairs(unsigned int *s,int i)
{
unsigned long p;
static int b=0,m=1;
int k=0,n,j;
for(j=b;j<m;j++)
{
p=(long)s[j]*(long)i+k;
k=p/10000;
s[j]=p-k*10000;
}
if(!s[b])b++;
if(k)s[m++]=k;
}
----------------解决方案--------------------------------------------------------
不用客气!互相学习,共同提高!
----------------解决方案--------------------------------------------------------
楼主给我解释一下好吗? 怎么把字符串里的数字转成浮点数 不用atof函数
另: 把楼主的源程序打印出来 研究了两天 好些地方看不懂。。。。。。。
----------------解决方案--------------------------------------------------------
哪里看不懂的话 可以发帖子过来 我会给你一一解释的 其实这个也没有多大的难度的
----------------解决方案--------------------------------------------------------
楼主,把这个计算机器程序缩减一下
只要求这样,怎么做?
算术表达式求值(包含括号的处理)
将任意一个算术表达式转化为逆波兰表示,并根据逆波兰表示计算表达式的值。
----------------解决方案--------------------------------------------------------