怎么用c语言编写简单计算器计算器的上一个结果

一个用C语言实现的科学计算器
使用C语言写的科学计算器,可以实现四则运算、三角函数运算、指对数运算;优先级正确;能智能屏蔽空格,能识别输入错误和运算错误,能实现继续运算、清空运算结果和有效退出的功能
#define INPUT_MAX 1000
#define NODE_MAX 500
#define NUM_OPT 20
#define LEN_OPT 6
#define NUM_OPS 200
typedef enum{
typedef struct{
//括号栈,检测括号是否匹配
char brackets[NUM_OPS];
int input(Node *in);
int translate(char *p,Node *re,int *len);
double translateopd(char *p,int *len);
int translateopt(char *p,int *len);
int cmp(const char *s,const char *d);
int calculate(Node *n,double *r);
int sclt(int opr,double *opd);
int dclt(int opr,double *opd1,double opd2);
int prid(int c);
/*功能:表达式输入和转换
接收输入并翻译为操作符和操作数存入表达式链
*输入:表达式链的地址
*输出:执行状态,正确返回1,错误返回0
int input(Node *in)
//input-&string
char ins[INPUT_MAX]={0};
int insi=0;
char temp_in=0;
int len=0;
//检测开头的空格
while(' '==(ins[0]=getchar()));
//检测是不是直接输入了一个回车
if(ins[0]!='\n')
temp_in=getchar();
//只能忽略多余空格
if(ins[insi]==' '&&temp_in==' ')
ins[++insi]=temp_
}while(temp_in!='\n');
ins[insi]=0;
//输入回车直接输出0
if(ins[0]=='\n')
in-&tp=Opd,in-&opd=0.0,in++;
//压入表达式链
while(ins[insi])
if(translate(ins+insi,in++,&len))
//自动添加等号
if((in-1)-&opt!='=')
in-&opt='=',in-&tp=Opt,in++;
in-&opt=-1,in-&tp=O
/*功能:翻译字符串为操作数或操作符
*输入:字符串地址,翻译返回节点,操作数和操作符长度返回地址
*输出:翻译结果状态
int translate(char *p,Node *re,int *len)
if(*p&='0'&&*p&='9')
re-&opd=translateopd(p,len);
else if(*p=='e'||*p=='p')
if(*p=='e')
re-&opd=M_E;
if(p[1]==' ')
(*len)++; //十分重要,此处必须加括号
if(p[1]=='i')
re-&opd=M_PI;
if(p[2]==' ')
re-&opt=translateopt(p,len);
if(re-&opt)
/*功能:翻译操作数
double translateopd(char *p,int *len)
int flag=0;
int pointnum=1;
double temp=0;
if(!flag&&p[i]!='.')
temp=temp*10+p[i++]-'0';
else if(!flag&&p[i]=='.')
flag=1,i++;
temp+=(p[i++]-'0')*pow(0.1,pointnum),pointnum++;
}while((p[i]&='0'&&p[i]&='9')||p[i]=='.');
if(p[i]==' ')
/*功能:翻译操作数
如果运算符非法,则返回0,合法则返回非零标志
int translateopt(char *p,int *len)
char fu[NUM_OPT][LEN_OPT]={&+&,&-&,&*&,&/&,&^&,&(&,&)&,&sin&,&cos&,&tan&,&asin&,&acos&,&atan&,&ln&,&lg&,&=&};
int fu_int[NUM_OPT]={'+','-','*','/','^','(',')','s','c','t','s'+'a','c'+'a','t'+'a','n','g','='};
for(i=0;itp==Opt&&n-&opt=='-')
OPRD[db]=0.0,db++; //Push(&OPRD,0.0);
//判断前面有没有负号
if(n-&tp==Opd)
OPRD[db]=n-&opd,db++,n++; //Push(&OPRD,n-&opd),n++;
//双目运算符
if(prid(n-&opt))
//if(!GetTop(OPRT,&top))
top=OPRT[tb-1];
if(n-&opt=='='||n-&opt==')')
if(n-&opt==')')
bb--; //if(!Pop(&brackets,&temp))
printf(&Bracket does not match!&);
OPRT[tb]=n-&opt,tb++,n++; //Push(&OPRT,n-&opt),n++;
if(prid(top)==0)
//Pop(&OPRD,&a);
//Pop(&OPRT,&o);
a=OPRD[db];
o=OPRT[tb];
if(sclt(o,&a))
OPRD[db]=a,db++; //Push(&OPRD,a);
if(prid(top)&=prid(n-&opt))
//Pop(&OPRD,&b);
//Pop(&OPRD,&a);
//Pop(&OPRT,&o);
b=OPRD[db];
a=OPRD[db];
o=OPRT[tb];
if(dclt(o,&a,b))
OPRD[db]=a,db++; //Push(&OPRD,a);
OPRT[tb]=n-&opt,tb++,n++; //Push(&OPRT,n-&opt),n++;
//单目运算符和括号
double x=0.0;
if(n-&opt=='(')
brackets[bb]='(',bb++; //Push(&brackets,'(');
if(len=calculate(n+1,&x))
OPRD[db]=x,db++; //Push(&OPRD,x);
n+=len,n++;
if(n-&tp==Opt&&n-&opt==-1)
printf(&Bracket does not match!&);
OPRT[tb]=n-&opt,tb++; //Push(&OPRT,n-&opt);
*r=OPRD[db-1];
return n-nb+1;
/*功能:单目运算
int sclt(int opr,double *opd)
switch(opr)
case 's':
*opd=sin(*opd);
case 'c':
*opd=cos(*opd);
case 't':
*opd=tan(*opd);
case 'a'+'s':
if(*opd&-1||*opd&1)
printf(&Beyond asin()!&);
*opd=asin(*opd);
case 'a'+'c':
if(*opd&-1||*opd&1)
printf(&Beyond acos()!&);
*opd=acos(*opd);
case 'a'+'t':
if(*opd&-3.&&*opd&3.)
*opd=atan(*opd);
printf(&Beyond atan()!&);
case 'n':
if(*opd&0)
*opd=log(*opd);
printf(&Beyond ln()!&);
case 'g':
if(*opd&0)
*opd=log10(*opd);
printf(&Beyond lg()!&);
/*功能:双目运算
int dclt(int opr,double *opd1,double opd2)
switch(opr)
case '+':
*opd1 = *opd1+opd2;
case '-':
*opd1 = *opd1-opd2;
case '*':
*opd1 = (*opd1)*opd2;
case '/':
if(opd2&pow(0.1,8)||opd2&0-pow(0.1,8))
*opd1 = (*opd1)/opd2;
printf(&Error 1/0 !&);
case '^':
*opd1 = pow(*opd1,opd2);
/*功能:判断优先级
int prid(int c)
case '+':
case '-':
case '=':
case ')':
case '*':
case '/':
case '^':
default :return 0;
int main()
Node nodes[NODE_MAX]={0};
double r=0.0;
//清空括号栈
bb=0; //InitStack(&brackets);
printf(&Enter: &);
if(!input(nodes))
printf(&Input Error!&);
if(calculate(nodes,&r))
printf(&Bracket does not match!&);
if(floor(r)==r)
printf(&%d&,(int)r);
printf(&%.4f&,r);
c=getchar();
if(c=='q') //退出
else if(c=='c') //清屏
system(&clear&);
if(c!='\n')
getchar();
printf(&Quit...\n&);C语言,简单计算器(上)C语言,简单计算器(上)前沿技术百家号由于工作需要最近在研究PHP扩展,无可避免的涉及到了C语言。从出了学校以后C语言在实际工作中还没有用到过,所以必须要先进行一点复习工作。个人认为对于熟悉一样东西说最好的方法是上手实践。于是便想起了当时大学的时候老师布置过的一道题目,用C语言实现简单数学表达式的分析和求值,比较遗憾的是当初没能把题目完成。就想着从新试一试,算是补一下当初的作业。还记得当初的思路是,循环C字符串。用链表将不同的计算项存储到链表中。然后在进行循环求值。如果遇到括号就递归调用。回忆并整理了一下当初的思路大致如下。1.输入 3+5*(2-6)/22.解析为3.计算 通过两次循环对不同优先级进行运算得出结果第一次对*/进行计算,拿当前节点,和节点的next节点,求值后将值赋给next节点,并删除自身节点第二次对+-进行求值,直到遇到end最初也打算按这个思路去实现的,之后发现解析的步骤会比较复杂,涉及到多次的字符串搜索,比对。再加上C本身不支持正则表达式,所以就放弃了当初的思路。找了一些相关的资料后发现了一种更简单也更科学的方法,那就是将输入转换成后缀表达式再进行求值,这后缀表达式究竟是什么呢,请继续看下去。一、后缀表达式百度百科介绍: 不包含括号,运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序,严格从左向右进行(不再考虑运算符的优先规则,如:(2 + 1) * 3 ,即2 1 + 3 *了解了后缀表达式才知道,原来我们习以为常的数学表达式被称之为中缀表达式。花了点时间研究了一下发现后缀表达式的计算还蛮简单的,也更符合计算机运算。计算方法,从左往右进行计算。取运算符号前两位数字进行运算,运算结果替代运算符以及前两位数字,持续运算到最右边得出结果。这么说起来可能比较难理解,我们看几个例子最简单的 21+计算过程为 2 + 1 = 3值为3普通的 325-2*+计算过程 从左往右先计算 2-5=-3,-3取代前面的25-之后为 3-32*+,完整的计算步骤如下计算2-5=3 计算完之后表达式为 3 -3 2 *+计算-3*2=-6 计算完之后表达式为 3 -6 +计算3+-6=-3 计算完之后表达式为 -3值为-3稍微复杂一点的 21+3*5387-/*-计算过程 从左往右先计算 2+1 = 3,4取代前面的21+之后为 33*5387-/*- 完整的计算步骤如下计算2+1=3 计算完之后表达式为 3 3 *5 3 8 7 -/*-计算3*3=9 计算完之后表达式为 9 5 3 8 7 -/*-计算8-7=1 计算完之后表达式为 9 5 3 1 /*-计算3/1=3 计算完之后表达式为 9 5 3 *-计算5*3=15 计算完之后表达式为 9 15 -计算9-15=-6 结果为 -6值为-6看完了以上结果,我们会发现每一次参与计算的数字,都是最靠近运算符号的两位数字。然后由运算出来的结果代替参与运算的数字和运算符,直到表达式只剩下一个值,计算完成。根据这样的规律,程序处理起来就简单了。1.从左往右的循环整个输入。2.判断是否是数字,如果是数字就保存起来。如果遇到符号,则把保存的前两个值取出来,计算后把本次计算结果存回去3.循环完成之后,剩下的表达式便是计算结果了根据如上规则不难发现每次参与计算的两个数字都是最后存进去的,这样一来我们便可以用栈轻松的完成这样一个程序了,下面跟大家简单介绍一下栈。二、栈百度百科的解释比较复杂,就不摘抄了。其实栈可以简单的理解为一个存放数据的空间,数据按照后进先出的原则进行存取。对数据的操作有push和pop,分别称之为压入,弹出。由于比较简单,所以直接用代码实现了一个简单的栈,包含如下四个方法。简单的进行测试,输入结果为item is : 1.120000item is : 2.8000002.8000001.120000实现了预期输出,一个简单的栈就搞定了,接下来就可以利用整个简单的栈来完成求值的函数了。三、后缀表达式求的具体实现由于栈已经实现了,所以只需要按照后缀表达式求值的逻辑进行运算在配合栈就可以实现整个计算过程了。方法比较简单,用while循环整字符串,在配合switch对数字和运算符做不同的处理就能够完成一个简单的后缀表达式求值函数了。以下是第一版的实现代码在第一个版本的过程中,遇到一个C语言知识点是 C语言的字符串指针指向的地址是字符串第一个字符的地址。所以当i为0的时候,&str[i] = &str, atof 接收的是一个字符串指针,如果使用 STACKpush(atof(&str[i])),i为0时,会将整个字符串传入进去转换。采用了一个char变量,讲str[i]拷贝出来,然后传入&num,则可以解决这个问题。其实这段程序里还涉及到一个指针运算的知识点,但是这里的程序里涉及还比较简单易懂,后续还有更难的地方涉及到这个知识点,所以先放到后面再跟大家分享。对上面的方法进行了测试,输入我们之前分析的三个表达式,得出结果如下printf("%f\n", calculate("21+")); //3printf("%f\n", calculate("325-2*+")); //-3printf("%f\n", calculate("21+3*5387-/*-")); //-6测试通过,跟之前的计算结果一直。以上便是一个简单的后缀表达式的计算程序了。进行了多几次的测试发现了一个小问题,就是目前无法进行多位数的识别。因为程序没一次都将一位数压入站内了。思考了一下在表达式的每个计算项上加了一个空格符作为数字的区分。变为 21 3 +这种形式,于是动手将代码做了一点小改动在switch 中加入了对空格的处理,以及多位数的处理//如果遇到空格,则重置标志位本文仅代表作者观点,不代表百度立场。系作者授权百家号发表,未经许可不得转载。前沿技术百家号最近更新:简介:科技改变世界,创意照明生活作者最新文章相关文章初学C语言,自己编了个计算器,带入几组数据没问题,不知道程序是否正确,应该怎样验证。求大神帮忙看看。
[问题点数:40分,结帖人cb]
初学C语言,自己编了个计算器,带入几组数据没问题,不知道程序是否正确,应该怎样验证。求大神帮忙看看。
[问题点数:40分,结帖人cb]
不显示删除回复
显示所有回复
显示星级回复
显示得分回复
只显示楼主
2016年5月 总版技术专家分月排行榜第二
2016年10月优秀大版主2016年8月论坛优秀大版主
2014年 总版技术专家分年内排行榜第二
2013年 总版技术专家分年内排行榜第三
匿名用户不能发表回复!|编写一个C语言程序,模拟一个计算器。
编写一个C语言程序,模拟一个计算器。
08-12-26 &
include &dos.h& /*DOS接口函数*/ #include &math.h& /*数学函数的定义*/ #include &conio.h& /*屏幕操作函数*/ #include &stdio.h& /*I/O函数*/ #include &stdlib.h& /*库函数*/ #include &stdarg.h& /*变量长度参数表*/ #include &graphics.h& /*图形函数*/ #include &string.h& /*字符串函数*/ #include &ctype.h& /*字符操作函数*/ #define UP 0x48 /*光标上移键*/ #define DOWN 0x50 /*光标下移键*/ #define LEFT 0x4b /*光标左移键*/ #define RIGHT 0x4d /*光标右移键*/ #define ENTER 0x0d /*回车键*/ void * /*全局变量,保存光标图象*/ struct /*使用调色板信息*/ int GraphD /* 图形设备驱动*/ int GraphM /* 图形模式值*/ int ErrorC /* 错误代码*/ int MaxC /* 可用颜色的最大数值*/ int MaxX, MaxY; /* 屏幕的最大分辨率*/ double AspectR /* 屏幕的像素比*/ void drawboder(void); /*画边框函数*/ void initialize(void); /*初始化函数*/ void computer(void); /*计算器计算函数*/ void changetextstyle(int font, int direction, int charsize); /*改变文本样式函数*/ void mwindow(char *header); /*窗口函数*/ int specialkey(void) ; /*获取特殊键函数*/ int arrow(); /*设置箭头光标函数*/ /*主函数*/ int main() { initialize();/* 设置系统进入图形模式 */ computer(); /*运行计算器 */ closegraph();/*系统关闭图形模式返回文本模式*/ return(0); /*结束程序*/ } /* 设置系统进入图形模式 */ void initialize(void) { int xasp, /* 用于读x和y方向纵横比*/ GraphDriver = DETECT; /* 自动检测显示器*/ initgraph( &GraphDriver, &GraphMode, && ); /*初始化图形系统*/ ErrorCode = graphresult(); /*读初始化结果*/ if( ErrorCode != grOk ) /*如果初始化时出现错误*/ { printf(&Graphics System Error: %s\n&, grapherrormsg( ErrorCode ) ); /*显示错误代码*/ exit( 1 ); /*退出*/ } getpalette( &palette ); /* 读面板信息*/ MaxColors = getmaxcolor() + 1; /* 读取颜色的最大值*/ MaxX = getmaxx(); /* 读屏幕尺寸 */ MaxY = getmaxy(); /* 读屏幕尺寸 */ getaspectratio( &xasp, &yasp ); /* 拷贝纵横比到变量中*/ AspectRatio = (double)xasp/(double)/* 计算纵横比值*/ } /*计算器函数*/ void computer(void) { st /*定义视口类型变量*/ int color, height, int x, y,x0,y0, i, j,v,m,n,act,flag=1; float num1=0,num2=0, /*操作数和计算结果变量*/ char cnum[5],str2[20]={&&},c,temp[20]={&&}; char str1[]=&9*/Qc=^%&;/* 定义字符串在按钮图形上显示的符号 */ mwindow( &Calculator& ); /* 显示主窗口 */ color = 7; /*设置灰颜色值*/ getviewsettings( &vp ); /* 读取当前窗口的大小*/ width=(vp.right+1)/10; /* 设置按钮宽度 */ height=(vp.bottom-10)/10 ; /*设置按钮高度 */ x = width /2; /*设置x的坐标值*/ y = height/2; /*设置y的坐标值*/ setfillstyle(SOLID_FILL, color+3); bar( x+width*2, y, x+7*width, y+height ); /*画一个二维矩形条显示运算数和结果*/ setcolor( color+3 ); /*设置淡绿颜色边框线*/ rectangle( x+width*2, y, x+7*width, y+height ); /*画一个矩形边框线*/ setcolor(RED); /*设置颜色为红色*/ outtextxy(x+3*width,y+height/2,&0.&); /*输出字符串&0.&*/ x =2*width-width/2; /*设置x的坐标值*/ y =2*height+height/2; /*设置y的坐标值*/ for( j=0 ; j&4 ; ++j ) /*画按钮*/ { for( i=0 ; i&5 ; ++i ) { setfillstyle(SOLID_FILL, color); setcolor(RED); bar( x, y, x+width, y+height ); /*画一个矩形条*/ rectangle( x, y, x+width, y+height ); sprintf(str2,&%c&,str1[j*5+i]); /*将字符保存到str2中*/ outtextxy( x+(width/2), y+height/2, str2); x =x+width+ (width / 2) ; /*移动列坐标*/ } y +=(height/2)*3; /* 移动行坐标*/ x =2*width-width/2; /*复位列坐标*/ } x0=2* y0=3* x=x0; y=y0; gotoxy(x,y); /*移动光标到x,y位置*/ arrow(); /*显示光标*/ putimage(x,y,rar,XOR_PUT); m=0; n=0; strcpy(str2,&&); /*设置str2为空串*/ while((v=specialkey())!=45) /*当压下Alt+x键结束程序,否则执行下面的循环*/ { while((v=specialkey())!=ENTER) /*当压下键不是回车时*/ { putimage(x,y,rar,XOR_PUT); /*显示光标图象*/ if(v==RIGHT) /*右移箭头时新位置计算*/ if(x&=x0+6*width) /*如果右移,移到尾,则移动到最左边字符位置*/ { x=x0; m=0; } else { x=x+width+width/2; m++; } /*否则,右移到下一个字符位置*/ if(v==LEFT) /*左移箭头时新位置计算*/ if(x&=x0) { x=x0+6* m=4; } /*如果移到头,再左移,则移动到最右边字符位置*/ else { x=x-width-width/2; m--; } /*否则,左移到前一个字符位置*/ if(v==UP) /*上移箭头时新位置计算*/ if(y&=y0) { y=y0+4*height+height/2; n=3; } /*如果移到头,再上移,则移动到最下边字符位置*/ else { y=y-height-height/2; n--; } /*否则,移到上边一个字符位置*/ if(v==DOWN) /*下移箭头时新位置计算*/ if(y&=7*height) { y=y0; n=0; } /*如果移到尾,再下移,则移动到最上边字符位置*/ else { y=y+height+height/2; n++; } /*否则,移到下边一个字符位置*/ putimage(x,y,rar,XOR_PUT); /*在新的位置显示光标箭头*/ } c=str1[n*5+m]; /*将字符保存到变量c中*/ if(isdigit(c)||c=='.') /*判断是否是数字或小数点*/ { if(flag==-1) /*如果标志为-1,表明为负数*/ { strcpy(str2,&-&); /*将负号连接到字符串中*/ flag=1; } /*将标志值恢复为1*/ sprintf(temp,&%c&,c); /*将字符保存到字符串变量temp中*/ strcat(str2,temp); /*将temp中的字符串连接到str2中*/ setfillstyle(SOLID_FILL,color+3); bar(2*width+width/2,height/2,15*width/2,3*height/2); outtextxy(5*width,height,str2); /*显示字符串*/ } if(c=='+') { num1=atof(str2); /*将第一个操作数转换为浮点数*/ strcpy(str2,&&); /*将str2清空*/ act=1; /*做计算加法标志值*/ setfillstyle(SOLID_FILL,color+3); bar(2*width+width/2,height/2,15*width/2,3*height/2); outtextxy(5*width,height,&0.&); /*显示字符串*/ } if(c=='-') { if(strcmp(str2,&&)==0) /*如果str2为空,说明是负号,而不是减号*/ flag=-1; /*设置负数标志*/ else { num1=atof(str2); /*将第二个操作数转换为浮点数*/ strcpy(str2,&&); /*将str2清空*/ act=2; /*做计算减法标志值*/ setfillstyle(SOLID_FILL,color+3); bar(2*width+width/2,height/2,15*width/2,3*height/2); /*画矩形*/ outtextxy(5*width,height,&0.&); /*显示字符串*/ } } if(c=='*') { num1=atof(str2); /*将第二个操作数转换为浮点数*/ strcpy(str2,&&); /*将str2清空*/ act=3; /*做计算乘法标志值*/ setfillstyle(SOLID_FILL,color+3); bar(2*width+width/2,height/2,15*width/2,3*height/2); outtextxy(5*width,height,&0.&); /*显示字符串*/ } if(c=='/') { num1=atof(str2); /*将第二个操作数转换为浮点数*/ strcpy(str2,&&); /*将str2清空*/ act=4; /*做计算除法标志值*/ setfillstyle(SOLID_FILL,color+3); bar(2*width+width/2,height/2,15*width/2,3*height/2); outtextxy(5*width,height,&0.&); /*显示字符串*/ } if(c=='^') { num1=atof(str2); /*将第二个操作数转换为浮点数*/ strcpy(str2,&&); /*将str2清空*/ act=5; /*做计算乘方标志值*/ setfillstyle(SOLID_FILL,color+3); /*设置用淡绿色实体填充*/ bar(2*width+width/2,height/2,15*width/2,3*height/2); /*画矩形*/ outtextxy(5*width,height,&0.&); /*显示字符串*/ } if(c=='%') { num1=atof(str2); /*将第二个操作数转换为浮点数*/ strcpy(str2,&&); /*将str2清空*/ act=6; /*做计算模运算乘方标志值*/ setfillstyle(SOLID_FILL,color+3); /*设置用淡绿色实体填充*/ bar(2*width+width/2,height/2,15*width/2,3*height/2); /*画矩形*/ outtextxy(5*width,height,&0.&); /*显示字符串*/ } if(c=='=') { num2=atof(str2); /*将第二个操作数转换为浮点数*/ switch(act) /*根据运算符号计算*/ { case 1:result=num1+num2; /*做加法*/ case 2:result=num1-num2; /*做减法*/ case 3:result=num1*num2; /*做乘法*/ case 4:result=num1/num2; /*做除法*/ case 5:result=pow(num1,num2); /*做x的y次方*/ case 6:result=fmod(num1,num2); /*做模运算*/ } setfillstyle(SOLID_FILL,color+3); /*设置用淡绿色实体填充*/ bar(2*width+width/2,height/2,15*width/2,3*height/2); /*覆盖结果区*/ sprintf(temp,&%f&,result); /*将结果保存到temp中*/ outtextxy(5*width,height,temp); /*显示结果*/ } if(c=='c') { num1=0; /*将两个操作数复位0,符号标志为1*/ num2=0; flag=1; strcpy(str2,&&); /*将str2清空*/ setfillstyle(SOLID_FILL,color+3); /*设置用淡绿色实体填充*/ bar(2*width+width/2,height/2,15*width/2,3*height/2); /*覆盖结果区*/ outtextxy(5*width,height,&0.&); /*显示字符串*/ } if(c=='Q')exit(0); /*如果选择了q回车,结束计算程序*/ } putimage(x,y,rar,XOR_PUT); /*在退出之前消去光标箭头*/
/*返回*/ } /*窗口函数*/ void mwindow( char *header ) {
cleardevice(); /* 清除图形屏幕 */ setcolor( MaxColors - 1 ); /* 设置当前颜色为白色*/ setviewport( 20, 20, MaxX/2, MaxY/2, 1 ); /* 设置视口大小 */ height = textheight( &H& ); /* 读取基本文本大小 */ settextstyle( DEFAULT_FONT, HORIZ_DIR, 1 );/*设置文本样式*/ settextjustify( CENTER_TEXT, TOP_TEXT );/*设置字符排列方式*/ outtextxy( MaxX/4, 2, header ); /*输出标题*/ setviewport( 20,20+height+4, MaxX/2+4, MaxY/2+20, 1 ); /*设置视口大小*/ drawboder(); /*画边框*/ } void drawboder(void) /*画边框*/ { st /*定义视口类型变量*/ setcolor( MaxColors - 1 ); /*设置当前颜色为白色 */ setlinestyle( SOLID_LINE, 0, NORM_WIDTH );/*设置画线方式*/ getviewsettings( &vp );/*将当前视口信息装入vp所指的结构中*/ rectangle( 0, 0, vp.right-vp.left, vp.bottom-vp.top ); /*画矩形边框*/ } /*设计鼠标图形函数*/ int arrow() {
int raw[]={4,4,4,8,6,8,14,16,16,16,8,6,8,4,4,4}; /*定义多边形坐标*/ setfillstyle(SOLID_FILL,2); /*设置填充模式*/ fillpoly(8,raw); /*画出一光标箭头*/ size=imagesize(4,4,16,16); /*测试图象大小*/ rar=malloc(size); /*分配内存区域*/ getimage(4,4,16,16,rar); /*存放光标箭头图象*/ putimage(4,4,rar,XOR_PUT); /*消去光标箭头图象*/ return 0; } /*按键函数*/ int specialkey(void) {
while(bioskey(1)==0); /*等待键盘输入*/ key=bioskey(0); /*键盘输入*/ key=key&0xff? key&0xff:key&&8; /*只取特殊键的扫描值,其余为0*/ return(key); /*返回键值*/ }
请登录后再发表评论!
#include &dos.h& /*DOS接口函数*/ #include &math.h& /*数学函数的定义*/ #include &conio.h& /*屏幕操作函数*/ #include &stdio.h& /*I/O函数*/ #include &stdlib.h& /*库函数*/ #include &stdarg.h& /*变量长度参数表*/ #include &graphics.h& /*图形函数*/ #include &string.h& /*字符串函数*/ #include &ctype.h& /*字符操作函数*/ #define UP 0x48 /*光标上移键*/ #define DOWN 0x50 /*光标下移键*/ #define LEFT 0x4b /*光标左移键*/ #define RIGHT 0x4d /*光标右移键*/ #define ENTER 0x0d /*回车键*/ void * /*全局变量,保存光标图象*/ struct /*使用调色板信息*/ int GraphD /* 图形设备驱动*/ int GraphM /* 图形模式值*/ int ErrorC /* 错误代码*/ int MaxC /* 可用颜色的最大数值*/ int MaxX, MaxY; /* 屏幕的最大分辨率*/ double AspectR /* 屏幕的像素比*/ void drawboder(void); /*画边框函数*/ void initialize(void); /*初始化函数*/ void computer(void); /*计算器计算函数*/ void changetextstyle(int font, int direction, int charsize); /*改变文本样式函数*/ void mwindow(char *header); /*窗口函数*/ int specialkey(void) ; /*获取特殊键函数*/ int arrow(); /*设置箭头光标函数*/ /*主函数*/ int main() { initialize();/* 设置系统进入图形模式 */ computer(); /*运行计算器 */ closegraph();/*系统关闭图形模式返回文本模式*/ return(0); /*结束程序*/ } /* 设置系统进入图形模式 */ void initialize(void) { int xasp, /* 用于读x和y方向纵横比*/ GraphDriver = DETECT; /* 自动检测显示器*/ initgraph( &GraphDriver, &GraphMode, && ); /*初始化图形系统*/ ErrorCode = graphresult(); /*读初始化结果*/ if( ErrorCode != grOk ) /*如果初始化时出现错误*/ { printf(&Graphics System Error: %s\n&, grapherrormsg( ErrorCode ) ); /*显示错误代码*/ exit( 1 ); /*退出*/ } getpalette( &palette ); /* 读面板信息*/ MaxColors = getmaxcolor() + 1; /* 读取颜色的最大值*/ MaxX = getmaxx(); /* 读屏幕尺寸 */ MaxY = getmaxy(); /* 读屏幕尺寸 */ getaspectratio( &xasp, &yasp ); /* 拷贝纵横比到变量中*/ AspectRatio = (double)xasp/(double)/* 计算纵横比值*/ } /*计算器函数*/ void computer(void) { st /*定义视口类型变量*/ int color, height, int x, y,x0,y0, i, j,v,m,n,act,flag=1; float num1=0,num2=0, /*操作数和计算结果变量*/ char cnum[5],str2[20]={&&},c,temp[20]={&&}; char str1[]=&9*/Qc=^%&;/* 定义字符串在按钮图形上显示的符号 */ mwindow( &Calculator& ); /* 显示主窗口 */ color = 7; /*设置灰颜色值*/ getviewsettings( &vp ); /* 读取当前窗口的大小*/ width=(vp.right+1)/10; /* 设置按钮宽度 */ height=(vp.bottom-10)/10 ; /*设置按钮高度 */ x = width /2; /*设置x的坐标值*/ y = height/2; /*设置y的坐标值*/ setfillstyle(SOLID_FILL, color+3); bar( x+width*2, y, x+7*width, y+height ); /*画一个二维矩形条显示运算数和结果*/ setcolor( color+3 ); /*设置淡绿颜色边框线*/ rectangle( x+width*2, y, x+7*width, y+height ); /*画一个矩形边框线*/ setcolor(RED); /*设置颜色为红色*/ outtextxy(x+3*width,y+height/2,&0.&); /*输出字符串&0.&*/ x =2*width-width/2; /*设置x的坐标值*/ y =2*height+height/2; /*设置y的坐标值*/ for( j=0 ; j&4 ; ++j ) /*画按钮*/ { for( i=0 ; i&5 ; ++i ) { setfillstyle(SOLID_FILL, color); setcolor(RED); bar( x, y, x+width, y+height ); /*画一个矩形条*/ rectangle( x, y, x+width, y+height ); sprintf(str2,&%c&,str1[j*5+i]); /*将字符保存到str2中*/ outtextxy( x+(width/2), y+height/2, str2); x =x+width+ (width / 2) ; /*移动列坐标*/ } y +=(height/2)*3; /* 移动行坐标*/ x =2*width-width/2; /*复位列坐标*/ } x0=2* y0=3* x=x0; y=y0; gotoxy(x,y); /*移动光标到x,y位置*/ arrow(); /*显示光标*/ putimage(x,y,rar,XOR_PUT); m=0; n=0; strcpy(str2,&&); /*设置str2为空串*/ while((v=specialkey())!=45) /*当压下Alt+x键结束程序,否则执行下面的循环*/ { while((v=specialkey())!=ENTER) /*当压下键不是回车时*/ { putimage(x,y,rar,XOR_PUT); /*显示光标图象*/ if(v==RIGHT) /*右移箭头时新位置计算*/ if(x&=x0+6*width) /*如果右移,移到尾,则移动到最左边字符位置*/ { x=x0; m=0; } else { x=x+width+width/2; m++; } /*否则,右移到下一个字符位置*/ if(v==LEFT) /*左移箭头时新位置计算*/ if(x&=x0) { x=x0+6* m=4; } /*如果移到头,再左移,则移动到最右边字符位置*/ else { x=x-width-width/2; m--; } /*否则,左移到前一个字符位置*/ if(v==UP) /*上移箭头时新位置计算*/ if(y&=y0) { y=y0+4*height+height/2; n=3; } /*如果移到头,再上移,则移动到最下边字符位置*/ else { y=y-height-height/2; n--; } /*否则,移到上边一个字符位置*/ if(v==DOWN) /*下移箭头时新位置计算*/ if(y&=7*height) { y=y0; n=0; } /*如果移到尾,再下移,则移动到最上边字符位置*/ else { y=y+height+height/2; n++; } /*否则,移到下边一个字符位置*/ putimage(x,y,rar,XOR_PUT); /*在新的位置显示光标箭头*/ } c=str1[n*5+m]; /*将字符保存到变量c中*/ if(isdigit(c)||c=='.') /*判断是否是数字或小数点*/ { if(flag==-1) /*如果标志为-1,表明为负数*/ { strcpy(str2,&-&); /*将负号连接到字符串中*/ flag=1; } /*将标志值恢复为1*/ sprintf(temp,&%c&,c); /*将字符保存到字符串变量temp中*/ strcat(str2,temp); /*将temp中的字符串连接到str2中*/ setfillstyle(SOLID_FILL,color+3); bar(2*width+width/2,height/2,15*width/2,3*height/2); outtextxy(5*width,height,str2); /*显示字符串*/ } if(c=='+') { num1=atof(str2); /*将第一个操作数转换为浮点数*/ strcpy(str2,&&); /*将str2清空*/ act=1; /*做计算加法标志值*/ setfillstyle(SOLID_FILL,color+3); bar(2*width+width/2,height/2,15*width/2,3*height/2); outtextxy(5*width,height,&0.&); /*显示字符串*/ } if(c=='-') { if(strcmp(str2,&&)==0) /*如果str2为空,说明是负号,而不是减号*/ flag=-1; /*设置负数标志*/ else { num1=atof(str2); /*将第二个操作数转换为浮点数*/ strcpy(str2,&&); /*将str2清空*/ act=2; /*做计算减法标志值*/ setfillstyle(SOLID_FILL,color+3); bar(2*width+width/2,height/2,15*width/2,3*height/2); /*画矩形*/ outtextxy(5*width,height,&0.&); /*显示字符串*/ } } if(c=='*') { num1=atof(str2); /*将第二个操作数转换为浮点数*/ strcpy(str2,&&); /*将str2清空*/ act=3; /*做计算乘法标志值*/ setfillstyle(SOLID_FILL,color+3); bar(2*width+width/2,height/2,15*width/2,3*height/2); outtextxy(5*width,height,&0.&); /*显示字符串*/ } if(c=='/') { num1=atof(str2); /*将第二个操作数转换为浮点数*/ strcpy(str2,&&); /*将str2清空*/ act=4; /*做计算除法标志值*/ setfillstyle(SOLID_FILL,color+3); bar(2*width+width/2,height/2,15*width/2,3*height/2); outtextxy(5*width,height,&0.&); /*显示字符串*/ } if(c=='^') { num1=atof(str2); /*将第二个操作数转换为浮点数*/ strcpy(str2,&&); /*将str2清空*/ act=5; /*做计算乘方标志值*/ setfillstyle(SOLID_FILL,color+3); /*设置用淡绿色实体填充*/ bar(2*width+width/2,height/2,15*width/2,3*height/2); /*画矩形*/ outtextxy(5*width,height,&0.&); /*显示字符串*/ } if(c=='%') { num1=atof(str2); /*将第二个操作数转换为浮点数*/ strcpy(str2,&&); /*将str2清空*/ act=6; /*做计算模运算乘方标志值*/ setfillstyle(SOLID_FILL,color+3); /*设置用淡绿色实体填充*/ bar(2*width+width/2,height/2,15*width/2,3*height/2); /*画矩形*/ outtextxy(5*width,height,&0.&); /*显示字符串*/ } if(c=='=') { num2=atof(str2); /*将第二个操作数转换为浮点数*/ switch(act) /*根据运算符号计算*/ { case 1:result=num1+num2; /*做加法*/ case 2:result=num1-num2; /*做减法*/ case 3:result=num1*num2; /*做乘法*/ case 4:result=num1/num2; /*做除法*/ case 5:result=pow(num1,num2); /*做x的y次方*/ case 6:result=fmod(num1,num2); /*做模运算*/ } setfillstyle(SOLID_FILL,color+3); /*设置用淡绿色实体填充*/ bar(2*width+width/2,height/2,15*width/2,3*height/2); /*覆盖结果区*/ sprintf(temp,&%f&,result); /*将结果保存到temp中*/ outtextxy(5*width,height,temp); /*显示结果*/ } if(c=='c') { num1=0; /*将两个操作数复位0,符号标志为1*/ num2=0; flag=1; strcpy(str2,&&); /*将str2清空*/ setfillstyle(SOLID_FILL,color+3); /*设置用淡绿色实体填充*/ bar(2*width+width/2,height/2,15*width/2,3*height/2); /*覆盖结果区*/ outtextxy(5*width,height,&0.&); /*显示字符串*/ } if(c=='Q')exit(0); /*如果选择了q回车,结束计算程序*/ } putimage(x,y,rar,XOR_PUT); /*在退出之前消去光标箭头*/
/*返回*/ } /*窗口函数*/ void mwindow( char *header ) {
cleardevice(); /* 清除图形屏幕 */ setcolor( MaxColors - 1 ); /* 设置当前颜色为白色*/ setviewport( 20, 20, MaxX/2, MaxY/2, 1 ); /* 设置视口大小 */ height = textheight( &H& ); /* 读取基本文本大小 */ settextstyle( DEFAULT_FONT, HORIZ_DIR, 1 );/*设置文本样式*/ settextjustify( CENTER_TEXT, TOP_TEXT );/*设置字符排列方式*/ outtextxy( MaxX/4, 2, header ); /*输出标题*/ setviewport( 20,20+height+4, MaxX/2+4, MaxY/2+20, 1 ); /*设置视口大小*/ drawboder(); /*画边框*/ } void drawboder(void) /*画边框*/ { st /*定义视口类型变量*/ setcolor( MaxColors - 1 ); /*设置当前颜色为白色 */ setlinestyle( SOLID_LINE, 0, NORM_WIDTH );/*设置画线方式*/ getviewsettings( &vp );/*将当前视口信息装入vp所指的结构中*/ rectangle( 0, 0, vp.right-vp.left, vp.bottom-vp.top ); /*画矩形边框*/ } /*设计鼠标图形函数*/ int arrow() {
int raw[]={4,4,4,8,6,8,14,16,16,16,8,6,8,4,4,4}; /*定义多边形坐标*/ setfillstyle(SOLID_FILL,2); /*设置填充模式*/ fillpoly(8,raw); /*画出一光标箭头*/ size=imagesize(4,4,16,16); /*测试图象大小*/ rar=malloc(size); /*分配内存区域*/ getimage(4,4,16,16,rar); /*存放光标箭头图象*/ putimage(4,4,rar,XOR_PUT); /*消去光标箭头图象*/ return 0; } /*按键函数*/ int specialkey(void) {
while(bioskey(1)==0); /*等待键盘输入*/ key=bioskey(0); /*键盘输入*/ key=key&0xff? key&0xff:key&&8; /*只取特殊键的扫描值,其余为0*/ return(key); /*返回键值*/ }
请登录后再发表评论!}

我要回帖

更多关于 c语言编写计算器程序 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信