简易计算器C语言代码.docx
《简易计算器C语言代码.docx》由会员分享,可在线阅读,更多相关《简易计算器C语言代码.docx(20页珍藏版)》请在冰豆网上搜索。
简易计算器C语言代码
简易计算器C语言代码
简易四则运算计算器
计算机工具地历史而言,中国古代最早采用地一种计算工具叫筹策,又叫做算筹,这种算筹多用竹子制成,也有用木头,兽骨充当材料的,大约270枚一束,放在布袋里可随身携带。
直到今天仍在使用的住算盘,是中国古代计算工具领域中的另一项发明明代时的住算盘已经与现代的住算盘几乎相同。
17世纪初,西方国家的计算工具有了较大的发展。
英国数学家纳尔发现了“纳皮尔算筹”;英国牧师奥却德发明了圆柱形对数计算尺,这种计算尺不仅能做加减乘涂,乘方和开方运算,甚至可以计算三角函数,指数函数和对数函数。
这些计算工具不仅带动了计算的发展,也为现代计算器发展尊定了良好的基础,成为现代社会应用广泛的计算工具,如手机,操作系统上附带的多功能计算器。
项目设计目的
掌握模块的划分;
掌握结构体定义;
掌握栈的操作;
掌握函数的定义;
掌握栈的基本操作;
掌握VC的基本绘图库;
掌握鼠标的响应操作;
目设计内容
设计一个含有界面的计算器,输入一个包含括号的表达式,使用栈数据类型实现整数的四则运算操作,开方运算。
项目设计要求
根据分析,系统要求实现以下几点基本功能:
可通过按钮输入数字、运算符;
能通过按钮实现退格、清除功能;
实现加、减、乘、除、开方运算功能;
实现括号运算;
显示运算结果;
良好的交互界面。
项目详细设计
功能模块图
根据系统功能要求,主要含有四大模块,分别是计算器界面设计模块、计算器按键控制模块、四则混合运算模块、计算器记忆处理模块。
计算器界面设计模块:
调用VC图形系统函数和字符函数画出计算器的界面,包括24个按钮和一个文本输入框。
计算机按键控制模块:
计算器通过键盘按键值的判断,执行相应的操作,如接收数字输入等。
计算器计算处理模块。
计算处理模块主要完成可以包括括号的表达式运算,运算包括加,减,乘,除、开方。
计算处理模块在按键控制模块中被调用执行。
处理模块是通过栈来实现的,分别定义了两个顺序栈,一个用来存放操作符栈,一个用来存放操作数栈。
计算器记忆处理模块。
记忆处理模块使计算其具有记忆功能。
记忆当前输入的表达式,给出一个最后的运算结果。
可以清楚部分或全部记忆的值。
系统流程图
图系统流程图
主要算法
比较运算符优先级:
程序里的涉及到的运算符有7个,分别是‘+’,‘-’,‘*’,‘/’,‘(’,‘)’,‘#’,它们之间的优先级关系用一个二维数组来存放,
intcmp[7][7]={
{2,2,1,1,1,2,2},
{2,2,1,1,1,2,2},
{2,2,2,2,1,2,2},
{2,2,2,2,1,2,2},
{1,1,1,1,1,3,0},
{2,2,2,2,0,2,2},
{1,1,1,1,1,0,3}};
其中3代表‘=’,2代表‘>’,1代表‘<’,0代表不可比。
charCompare(charch1,charch2)
{
inti,m,n;
charpri;
intpriority;
for(i=0;i<7;i++)//找到相比较的两个运算符在比较矩阵里的相对位置
{
if(ch1==ops[i])
m=i;
if(ch2==ops[i])
n=i;
}
priority=cmp[m][n];
switch(priority)
{
case1:
pri='<';
break;
case2:
pri='>';
break;
case3:
pri='=';
break;
case0:
pri='$';
printf("表达式错误!
\n");
break;
}
returnpri;
}
主要代码
1.计算器界面设计
利用VC绘图库函数设计一个相对友好的操作界面。
关于VC绘图库的介绍在本书第二章。
界面图像如下:
图:
计算器界面
画计算机界面。
initgraph(500,300);//这里和TC略有区别
bar(15,15,480,70);
setcolor(WHITE);
rectangle(10,10,490,290);
setcolor(WHITE);
for(j=0;j<2;j++)
for(i=0;i<7;i++)
{if(i<3)circle(55+65*i,110+65*j,20);
elserectangle(55+65*i-20,110+65*j-20,55+65*i+20,110+65*j+20);}
for(i=0;i<7;i++)
{
if(i<4)circle(55+65*i,110+65*j,20);
elserectangle(55+65*i-20,110+65*j-20,55+65*i+20,110+65*j+20);
}
outtextxy(50,105,"7");
outtextxy(115,105,"8");
outtextxy(180,105,"9");
outtextxy(240,105,"C");
outtextxy(310,105,"+");
outtextxy(375,105,"(");
outtextxy(440,105,")");
outtextxy(50,170,"4");
outtextxy(115,170,"5");
outtextxy(180,170,"6");
outtextxy(240,170,".");
outtextxy(310,170,"-");
outtextxy(370,170,"sqrt");
outtextxy(440,170,"<-");
outtextxy(50,235,"3");
outtextxy(115,235,"2");
outtextxy(180,235,"1");
outtextxy(245,235,"0");
outtextxy(310,235,"*");
outtextxy(375,235,"/");
outtextxy(440,235,"=");
2.按键响应操作
当用户通过鼠标左键按下‘0’,‘1’,‘2’,‘3’,‘4’,‘5’,‘6’,‘7’,‘8’,‘9’,‘.’,‘+’,‘—’,‘*’,‘/’,‘(’,‘)’,‘=’,这些键时,字符按点击顺序在输出文本框输出;当用户点击‘<—’,表示退一格操作;当用户点击‘=’,在文本块输出表达式结果;当用户按下‘C’时,文本框清空。
MOUSEMSGm;
m=GetMouseMsg();//记录鼠标操作
i=0;
while(true)
{
m=GetMouseMsg();//记录鼠标操作
if(m.uMsg==WM_LBUTTONDOWN)
{setcolor(BLACK);
if(m.x>35&&m.x<=75&&m.y>90&&m.y<130){strcat(string,"7");outtextxy(25,40,string);}
if(m.x>100&&m.x<=140&&m.y>90&&m.y<130){strcat(string,"8");outtextxy(25,40,string);}
if(m.x>165&&m.x<=205&&m.y>90&&m.y<130){strcat(string,"9");outtextxy(25,40,string);}
if(m.x>225&&m.x<=265&&m.y>90&&m.y<130)
{setcolor(WHITE);bar(15,15,480,70);strcpy(string,"");}//C
if(m.x>290&&m.x<=330&&m.y>90&&m.y<130){strcat(string,"+");outtextxy(25,40,string);}
if(m.x>355&&m.x<=395&&m.y>90&&m.y<130){strcat(string,"(");outtextxy(25,40,string);}
if(m.x>420&&m.x<=460&&m.y>90&&m.y<130){strcat(string,")");outtextxy(25,40,string);}
if(m.x>35&&m.x<=75&&m.y>155&&m.y<195){strcat(string,"4");outtextxy(25,40,string);}
if(m.x>100&&m.x<=140&&m.y>155&&m.y<195){strcat(string,"5");outtextxy(25,40,string);}
if(m.x>165&&m.x<=205&&m.y>155&&m.y<195){strcat(string,"6");outtextxy(25,40,string);}
if(m.x>225&&m.x<=265&&m.y>155&&m.y<195){strcat(string,".");outtextxy(25,40,string);}
if(m.x>290&&m.x<=330&&m.y>155&&m.y<195){strcat(string,"-");setcolor(BLACK);outtextxy(25,40,string);}
if(m.x>355&&m.x<=395&&m.y>155&&m.y<195)//lg
{
n=strlen(string);
switch(n)//不超过5位
{
case5:
i=string[0]*10000+string[1]*1000+string[2]*100+string[3]*10+string[4];break;
case4:
i=string[0]*1000+string[1]*100+string[2]*10+string[3];break;
case3:
i=string[0]*100+string[1]*10+string[2];break;
case2:
i=string[0]*10+string[1];break;
case1:
i=string[1];break;
}
itoa(sqrt(i),string,10);
setcolor(WHITE);bar(15,15,480,70);setcolor(BLACK);
outtextxy(25,40,string);
}
if(m.x>420&&m.x<=460&&m.y>155&&m.y<195){n=strlen(string);printf("n=%d.",n);string[n-1]='\0';bar(15,15,480,70);setcolor(BLACK);outtextxy(25,40,string);}//<-
if(m.x>35&&m.x<=75&&m.y>215&&m.y<255){strcat(string,"3");outtextxy(25,40,string);}
if(m.x>100&&m.x<=140&&m.y>215&&m.y<255){strcat(string,"2");outtextxy(25,40,string);}
if(m.x>165&&m.x<=205&&m.y>215&&m.y<255){strcat(string,"1");outtextxy(25,40,string);}
if(m.x>225&&m.x<=265&&m.y>215&&m.y<255){strcat(string,"0");outtextxy(25,40,string);}
if(m.x>290&&m.x<=330&&m.y>215&&m.y<255){strcat(string,"*");outtextxy(25,40,string);}
if(m.x>355&&m.x<=395&&m.y>215&&m.y<255){strcat(string,"/");outtextxy(25,40,string);}
if(m.x>420&&m.x<=460&&m.y>215&&m.y<255)
{
strcpy(str1,string);
strcat(string,"=");
outtextxy(25,40,string);
strcat(str1,"#");
itoa(ExpEvaluation(str1),str2,10);
strcat(string,str2);
outtextxy(25,40,string);
}
}
3.利用栈的基本操作,实现表达式的求值。
定义两个顺序栈及顺序栈的基本操作:
初始化栈,判断栈空,取栈顶元素,入栈,出战,实现操作数的四则运算。
typedefstruct
{
charelem[Stack_Size];
inttop;
}SeqStack;
//运算数栈的定义
typedefstruct
{
intelem[Stack_Size];
inttop;
}SeqStackOperand;
//初始化运算符栈
voidInitStack(SeqStack*S)
{
S->top=-1;
}
//初始化运算数栈
voidInitStacknOperand(SeqStackOperand*S)
{
S->top=-1;
}
//判断栈S为空栈时返回值为真,反之为假
intIsEmpty(SeqStack*S)
{
return(S->top==-1?
TRUE:
FALSE);
}
//判断栈S为空栈时返回值为真,反之为假
intIsEmptynOperand(SeqStackOperand*S)
{
return(S->top==-1?
TRUE:
FALSE);
}
//判断栈S为满栈时返回值为真,反之为假
intIsFull(SeqStack*S)
{
return(S->top==Stack_Size-1?
TRUE:
FALSE);
}
//判断栈S为满栈时返回值为真,反之为假
intIsFullOperand(SeqStackOperand*S)
{
return(S->top==Stack_Size-1?
TRUE:
FALSE);
}
//运算符栈入栈函数
intPush(SeqStack*S,charx)
{
if(S->top==Stack_Size-1)
{
printf("Stackisfull!
\n");
returnFALSE;
}
else
{
S->top++;
S->elem[S->top]=x;
returnTRUE;
}
}
//运算数栈入栈函数
intPushOperand(SeqStackOperand*S,intx)
{
if(S->top==Stack_Size-1)
{
printf("Stackisfull!
\n");
returnFALSE;
}
else
{
S->top++;
S->elem[S->top]=x;
returnTRUE;
}
}
//运算符栈出栈函数
intPop(SeqStack*S,char*x)
{
if(S->top==-1)
{
printf("运算符栈空!
\n");
returnFALSE;
}
else
{
*x=S->elem[S->top];
S->top--;
returnTRUE;
}
}
//运算数栈出栈函数
intPopOperand(SeqStackOperand*S,int*x)
{
if(S->top==-1)
{
printf("运算符栈空!
\n");
returnFALSE;
}
else
{
*x=S->elem[S->top];
S->top--;
returnTRUE;
}
}
//运算符栈取栈顶元素函数
charGetTop(SeqStack*S)
{
if(S->top==-1)
{
printf("运算符栈为空!
\n");
returnFALSE;
}
else
{
return(S->elem[S->top]);
}
}
//运算数栈取栈顶元素函数
intGetTopOperand(SeqStackOperand*S)
{
if(S->top==-1)
{
printf("运算符栈为空!
\n");
returnFALSE;
}
else
{
return(S->elem[S->top]);
}
}
//判断输入字符是否为运算符函数,是返回TRUE,不是返回FALSE
intIsoperator(charch)
{
inti;
for(i=0;i<7;i++)
{
if(ch==ops[i])
returnTRUE;
}
returnFALSE;
}
//比较运算符优先级函数
charCompare(charch1,charch2)
{
inti,m,n;
charpri;
intpriority;
for(i=0;i<7;i++)//找到相比较的两个运算符在比较矩阵里的相对位置
{
if(ch1==ops[i])
m=i;
if(ch2==ops[i])
n=i;
}
priority=cmp[m][n];
switch(priority)
{
case1:
pri='<';
break;
case2:
pri='>';
break;
case3:
pri='=';
break;
case0:
pri='$';
printf("表达式错误!
\n");
break;
}
returnpri;
}
//运算函数
intExecute(inta,charop,intb)
{
intresult;
switch(op)
{
case'+':
result=a+b;
break;
case'-':
result=a-b;
break;
case'*':
result=a*b;
break;
case'/':
result=a/b;
break;
}
returnresult;
}
/*读入一个简单算术表达式并计算其值.operator和operand分别为运算符栈和运
算数栈,OPS为运算符集合*/
intExpEvaluation(char*str)
{
inta,b,v,temp;
charch,op;
inti=0;
SeqStackoperatordata;
SeqStackOperandoperand;
InitStack(&operatordata);
InitStacknOperand(&operand);
Push(&operatordata,'#');
ch=*str++;
while(ch!
='#'||GetTop(&operatordata)!
='#')
{
if(!
Isoperator(ch))
{
temp=ch-'0';//将字符转换为十进制数
ch=*str++;
i++;
while(!
Isoperator(ch))
{
temp=temp*10+ch-'0';//将逐个读入运算数的各位转化为十进制数
ch=*str++;
i++;
}
PushOperand(&operand,temp);
}
else
{
switch(Compare(GetTop(&operatordata),ch))
{
case'<':
Push(&operatordata,ch);
ch=*str++;
i++;
break;
case'=':
Pop(&operatordata,&op);
ch=*str++;
i++;
break;
case'>':
Pop(&operatordata,&op);
PopOperand(&operand,&b);
PopOperand(&operand,&a);
v=Execute(a,op,b);//对a和b进行op运算
PushOperand(&operand,v);
break;
}
}
}//endwhile
v=GetTopOperand(&operand);
returnv;
}
小结
知识点:
VC绘图库
鼠标按键响应操作
结构体
定义顺序栈
顺序栈的基本操作:
初始化栈、判断栈是否为空、取栈顶元素、入栈、出栈
功能扩充
实现取对数、正弦、余弦等一些函数功能。