当前位置: 代码迷 >> C语言 >> [原创]计算器程序(可用)
  详细解决方案

[原创]计算器程序(可用)

热度:690   发布时间:2004-04-16 16:25:00.0
[原创]计算器程序(可用)

下面这个程序支持加+ 减- 乘* 除/ 阶乘! 开方? 平方^ 取模% 等运算 支持括号和括号内优先级 可以输入负数 不过输入负数时需要用括号括上 这个程序 一定有不少 缺点 我也没有用一些表达式 进行运算验证 这个验证的过程就交给大家把 如果各位发现输入的表达式 计算错误的话 请将表达式和结果 发到帖子上来 我会修改的 如果哪位有兴致的话 可以将一些不完善的功能 修改也发到帖子上来 供大家共同学习进步 #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编辑过]

搜索更多相关的解决方案: 计算器  括号  include  math  

----------------解决方案--------------------------------------------------------

奇怪了 前几天在我朋友那台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函数

另: 把楼主的源程序打印出来 研究了两天 好些地方看不懂。。。。。。。


----------------解决方案--------------------------------------------------------
哪里看不懂的话 可以发帖子过来 我会给你一一解释的 其实这个也没有多大的难度的
----------------解决方案--------------------------------------------------------

楼主,把这个计算机器程序缩减一下

只要求这样,怎么做?

算术表达式求值(包含括号的处理) 将任意一个算术表达式转化为逆波兰表示,并根据逆波兰表示计算表达式的值。



----------------解决方案--------------------------------------------------------
  相关解决方案