科学计算器课程设计报
告C课程设计
集团标准化工作小组 [Q8QX9QT-X8QQB8Q8-NQ8QJ8-M8QMN]
计算机科学与技术学部
C++课程设计
题 目 科学计算器 学 部 计算机科学与技术 班 级 计科1103 指 导 教 师 李 军 姓 名 刘 明 学 号
2012年6月27日
摘 要
计算器的产生和发展是建立在电子计算机基础之上的。硬件方面,自1946年第一台电子计算机诞生以来,计算机技术的发展可谓日新月异,从庞大的只能在实验室里供研究使用的计算机到如今能适应不同环境满足不同需求的各种各样的计算机;运算速度从每秒几千次到每秒几百亿次;处理器从焊有上百万个电子管的大的惊人的电子板到只有指甲大小的集成电路;现在计算机在硬件方面的发展已达到了每三个月更新换代一次的惊人速度。软件方面,也已从机器语言、汇编语言、高级语言发展到现如今的第四代语言——非结构化、面向对象、可视化的语言。
在这个计算器里面,我们实现了简单的四则运算以及更高功能的科学计算,它的外观简洁美观,使人们能快捷简单的操作。能准确的得到计算结果,大大减少了数字计算所需要的时间,为人们的生活带来便利。此系统在Windows 7环境下,使用VC++ 进行编写。
简单计算器包括双目运算和单目运算功能,双目运算符包含基本的四则运算及乘幂功能,单目运算符包含正余弦,对数,开方,阶乘,倒数,进制转换等运算。可对其输入任意操作数,包括小数和整数及正数和负数进行以上的所有运算并能连续运算。并且包含清除,退格功能等。我们所做的计算器其功能较Windows 7下的计算器还是很不够多,没有其菜单的实现功能项,没有其小巧的标准计算器。
关键词: 计算器;运算;VC++等
课程设计任务分配表:
表1 分配信息表 姓名 主要工作 组长 组员 凡力强 课程设计成绩表: 表2 成绩表 刘 明 舒兆月 程序设计和编写 实验报告书的制作 实验报告书的制作 姓名 组长 组员 刘 明 舒兆月 凡力强 学号 班级 计科1103 计科1103 计科1103 成绩
采用的类的数据类型:
class CCalculatorDlg : public CDialog { public:
void clean_aliter(); CString OLD_ANSWER;
m_POINT m_Pow m_SQRT m_DIVID 在输入框显示按键计算m_CE 信息 m_C m_BACKSPACE 计算结果输m_LN 出到输出框m_LOG m_SIN m_COS m_TAN m_ACOS m_ATAN m_Xor m_BUTTON43 m_MOD m_BUTTON40 m_BUTTON49 m_BUTTON48 m_BUTTON47 选择角度 void out_change(int system); CCalculatorDlg(CWnd* pParent = NULL); 开 始 选择进制 IDC_POW IDC_SQRT IDC_DIVID 进行计算类IDC_CE 型运算IDC_C IDC_BACKSPACE IDC_Ln 错误IDC_Log汇总 IDC_Sin IDC_Cos IDC_Tan IDC_ACOS IDC_ATAN IDC_XOR IDC_BUTTON43 IDC_MOD IDC_BUTTON40 IDC_BUTTON49 IDC_BUTTON48 IDC_BUTTON47 如图 设计思路图 采取默认形 势 x^y Sqrt 选择/ 键值 CE C Backspace 不同计算Ln 类型进行Log Sin Cos束 结 Tan acos atan Xor MS Mod Dms Ave Sum S
IDC_NOT IDC_BUTTON46 IDC_PI IDC_BUTTON42 IDC_BUTTON45 IDC_Equal 变量的定义以及初始化
Not Dat pi M+ MC = m_NOT m_BUTTON46 m_PI m_BUTTON42 m_BUTTON45 m_EQUAL int Sel,EndSel; //定义输入或插入时光标的位置
int Expr_pos; //词法分析表达式时,标记当前字符位置 int OS_pos ; //操作数栈顶位置
int old_pos; //历史表达式的位置
int old_head; //历史表达式数组中最最前位置
int old_back; //历史表达式数组中最最后位置 int error_mark; //标记表达式错误
int parentheses_count; //记录表达式中括号的个数 double operand_Stack[200]; //操作数栈
CString old_expression[20]; //表达式历史记录 //以上为定义部分,以下为初始化部分 Sel=0; //输入的光标位置 EndSel=0; //插入光标的位置 Expr_pos = 0; //当前字符的位置 OS_pos = 0 ; //操作数栈顶位置 old_pos=old_head=old_back=0;//历史表达式的位置 error_mark=0; //表达式错误 parentheses_count=0; //括号的个数 OLD_ANSWER = _T(\"\"); //初始化
第三章 系统实现
窗体设计
利用MFC AppWinzard生成计算器应用程序框架具体步骤如下:
(1)执行VC++ 程序,选择文件——新建命令,转到工程选项卡,选择MFC AppWizard(exe)选项,然后在工程名称输入名字,一般以C开头,也可以自定义,位置路径自定义。
(2)单击确定,弹出MFC 应用程序向导-步骤1对话框。选中单选按钮基本对话框,单击完成即可,如图所示: (1)为控件添加成员变量已经在系统设计里面列举出,这里就不再重复; (2)为控件添加消息,查看-类向导命令,转到Message Maps选项卡,为控件添加BN_CLICKED消息,单击确定即可,具体哪些控件这里就不再详细介绍了。
程序核心代码
void CCalculatorDlg::OnNumberKey(UINT nID) //按键输入 { (Sel,EndSel); //得到输入框的光标位置 switch(nID) {// 在光标位置插入按钮表示的字符, 在输入框插入相应的数值 case IDC_0:{ (Sel,\"0\");break;} case IDC_1:{ (Sel,\"1\");break;} case IDC_2:{ (Sel,\"2\");break;} case IDC_3:{ (Sel,\"3\");break;} case IDC_4:{ (Sel,\"4\");break;} case IDC_5:{ (Sel,\"5\");break;} case IDC_6:{ (Sel,\"6\");break;} case IDC_7:{ (Sel,\"7\");break;} case IDC_8:{ (Sel,\"8\");break;} case IDC_9:{ (Sel,\"9\");break;} case IDC_A:{ (Sel,\"A\");break;} case IDC_B:{ (Sel,\"B\");break;} case IDC_C:{ (Sel,\"C\");break;} case IDC_D:{ (Sel,\"D\");break;} case IDC_E:{ (Sel,\"E\");break;} case IDC_F:{ (Sel,\"F\");break;} } Sel++; //光标后移 UpdateData(FALSE);
(Sel,Sel); //更新输入框光标后移位置 UpdateData(FALSE); }
voidCCalculatorDlg::compute(OperatorOp) {//根据操作计算类型,计算结果 switch(Op) {
caseOpAdd:
{operand_Stack[OS_pos-2]+=operand_Stack[OS_pos-1];OS_pos--;break;} caseOpSubtract:
{operand_Stack[OS_pos-2]-=operand_Stack[OS_pos-1];OS_pos--;break;} caseOpMultiply:
{operand_Stack[OS_pos-2]*=operand_Stack[OS_pos-1];OS_pos--;break;} caseOpDivide:
{if(operand_Stack[OS_pos-1]==0){error(5);break;} else
{operand_Stack[OS_pos-2]/=operand_Stack[OS_pos-1]; OS_pos--;break; }}
caseOpMod:
{if(operand_Stack[OS_pos-1]==0){error(5);break;} else
{ __int64temp=0;
temp=(__int64)(operand_Stack[OS_pos-2]/operand_Stack[OS_pos-1]); operand_Stack[OS_pos-1]*=temp;
operand_Stack[OS_pos-2]-=operand_Stack[OS_pos-1]; OS_pos--;break;} } caseOpPower:
{operand_Stack[OS_pos-2]=pow(operand_Stack[OS_pos-2],operand_Stack[OS_pos-1]);
OS_pos--;break;} caseOpLog:
{operand_Stack[OS_pos-1]=log10(operand_Stack[OS_pos-1]);break;} caseOpLn:
{operand_Stack[OS_pos-1]=log(operand_Stack[OS_pos-1]);break;} caseOpSqrt:
{operand_Stack[OS_pos-1]=sqrt(operand_Stack[OS_pos-1]);break;} caseOpExp: { operand_Stack[OS_pos-1]=exp(operand_Stack[OS_pos-1]);
break;}
caseOpSin:
{if(m_Radio2==0)operand_Stack[OS_pos-1]=operand_Stack[OS_pos-1]*PI/180;
operand_Stack[OS_pos-1]=sin(operand_Stack[OS_pos-1]); break;} caseOpCos:
{if(m_Radio2==0)operand_Stack[OS_pos-1]=operand_Stack[OS_pos-1]*PI/180;
operand_Stack[OS_pos-1]=cos(operand_Stack[OS_pos-1]); break;}
caseOpTan:
{if(m_Radio2==0)operand_Stack[OS_pos-1]=operand_Stack[OS_pos-1]*PI/180;operand_Stack[OS_pos-1]=tan(operand_Stack[OS_pos-1]);break;}
caseOpAsin:
{ if(operand_Stack[OS_pos-1]>1||operand_Stack[OS_pos-1]<-1) {error(9);return;}
operand_Stack[OS_pos-1]=asin(operand_Stack[OS_pos-1]); if(m_Radio2==0)
operand_Stack[OS_pos-1]=operand_Stack[OS_pos-1]*180/PI; break;}
caseOpAcos: { if(operand_Stack[OS_pos-1]>1||operand_Stack[OS_pos-1]<-1) {error(9);return;} operand_Stack[OS_pos-1]=acos(operand_Stack[OS_pos-1]); if(m_Radio2==0)
operand_Stack[OS_pos-1]=operand_Stack[OS_pos-1]*180/PI; break; }
caseOpAtan:
{ operand_Stack[OS_pos-1]=atan(operand_Stack[OS_pos-1]); if(m_Radio2==0)
operand_Stack[OS_pos-1]=operand_Stack[OS_pos-1]*180/PI; break; }
caseOpFactorial: { if(OS_pos<=0){error(1);return;} longk; k=(long)operand_Stack[OS_pos-1]; if(k 提示错误的核心代码 void CCalculatorDlg::error(int error_type) //错误类型 { //错误处理 switch(error_type) { case 1: {m_result=\"错误:缺少操作数!\";break;} case 2: {m_result=\"错误:括号不匹配!\";break;} case 3: {m_result=\"错误:函数名不正确!!\";break;} case 4: {m_result=\"错误:非法输入!!\";break;} case 5: {m_result=\"错误:出现除数为零!!\";break;} case 6: {m_result=\"错误:函数缺少括号!!\";break;} case 7: {m_result=\"错误:缺少运算符!!\";break;} case 8: {m_result=\"错误:阶乘操作数不是整数!!\";break;} case 9: {m_result=\"asin和acos函数计算必须在[-1,1]内!! \";break;} } error_mark=1; } voidCCalculatorDlg::getword(WordType&w_type,Operator&Fun_Ope,intsystem)//进制转为浮点型 {//词法分析器,参数w_type,Fun_Ope,system分别表示单词类型,操作运算类型,进制类型 intt=(); if(t<=0){error(4);return;}//表达式为空则返回 if(Expr_pos if((Expr_pos+1) {//根据传来的进制类型,把字符串表示的数字转换为浮点数 case0:{if(!getword16()){error(4);return;}break;} case1:{if(!getword10()){error(4);return;}break;} case2:{if(!getword8()){error(4); return ;} break;} case3:{if(!getword2()){error(4);return ; }break;} default:{error(4);return;} } w_type=Tynum;//单词类型为数字 return; } if(m_expression[Expr_pos]>='a'&& m_expression[Expr_pos]<='z') {/*当前字符为字母则 ,把字母串保存到str中 */ char str[100]=\"\"; int i=0; while(Expr_pos { str[i]=m_expression[Expr_pos]; i++; Expr_pos++; } if(Expr_pos>=t){error(3);w_type=TyFun;return;} //表达式结束,则报错 /* ***以下ifelse语句为匹配字符串*** */ if(strcmp(str,\"ln\")==0){Fun_Ope=OpLn;} elseif(strcmp(str,\"log\")==0){Fun_Ope=OpLog;} elseif(strcmp(str,\"sqrt\")==0){Fun_Ope=OpSqrt;} elseif(strcmp(str,\"exp\")==0){Fun_Ope=OpExp;} elseif(strcmp(str,\"sin\")==0){Fun_Ope=OpSin;} elseif(strcmp(str,\"cos\")==0){Fun_Ope=OpCos;} elseif(strcmp(str,\"tan\")==0){Fun_Ope=OpTan;} elseif(strcmp(str,\"asin\")==0){Fun_Ope=OpAsin;} elseif(strcmp(str,\"acos\")==0){Fun_Ope=OpAcos;} elseif(strcmp(str,\"atan\")==0){Fun_Ope=OpAtan;} //elseif(m_expression[Expr_pos]=='('){w_type=TyFun;} else{error(3);w_type=TyFun;return;} //匹配不到函数单词,报错 w_type=TyFun;return;} switch(m_expression[Expr_pos]) {/*当前字符为操作运算符,则设置单词类型,和操作运算*/ case'+':{Fun_Ope=OpAdd;Expr_pos++;w_type=oper;break;} case'-':{Fun_Ope=OpSubtract;Expr_pos++;w_type=oper;break;} case'*':{Fun_Ope=OpMultiply;Expr_pos++;w_type=oper;break;} case'/':{Fun_Ope=OpDivide; Expr_pos++;w_type=oper;break;} case'^':{Fun_Ope=OpPower; Expr_pos++;w_type=oper;break;} case'(':{Fun_Ope=Left_par;Expr_pos++;w_type=oper;break;} case')':{Fun_Ope=Right_par; Expr_pos++;w_type=oper;break;} case'%':{Fun_Ope=OpMod; Expr_pos++;w_type=oper;break;} default:{error(4);return;}//其他字符都为非法字符,报错 } } elseif(Expr_pos==t)w_type=TyEnd;//表达式已结束,返回 else{error(4);return;}} void CCalculatorDlg::OnOctal() //八进制单选按钮消息响应函数 { // TODO: Add your control notification handler code here WordType type ; Operator Ope; CString result; int system; system = m_Radio1; m_Radio1 = 2 ; if()>0) m_expression = OLD_ANSWER; UpdateData(FALSE); getword(type,Ope,system); if(type==Tynum&&(!error_mark)&&(Expr_pos==())) { out_change(m_Radio1); result = m_result; clean_all(); m_expression = m_result = result; UpdateData(FALSE) Sel = (); (Sel,Sel); UpdateData(FALSE); } else { Expr_pos = 0; OS_pos = 0 ; error_mark=0; parentheses_count=0; m_result = _T(\"\"); } (TRUE); (TRUE); (TRUE); (TRUE); (TRUE); (TRUE); (FALSE); (FALSE); (FALSE); (FALSE); (FALSE); (FALSE); (FALSE); (FALSE); (FALSE); } void CCalculatorDlg::OnBinary() //二进制单选按钮消息响应函数 { // TODO: Add your control notification handler code here //E_AddSub(); WordType type ; Operator Ope; CString result; int system; system = m_Radio1; m_Radio1 = 3 ; if()>0) m_expression = OLD_ANSWER; UpdateData(FALSE); getword(type,Ope,system); if(type==Tynum&&(!error_mark)&&(Expr_pos==())) { out_change(m_Radio1); result = m_result; clean_all(); m_expression = m_result = result; UpdateData(FALSE); Sel = (); (Sel,Sel); UpdateData(FALSE); } else { Expr_pos = 0; OS_pos = 0 ; error_mark=0; parentheses_count=0; m_result = _T(\"\"); } (FALSE); (FALSE); (FALSE); (FALSE); (FALSE); (FALSE); (FALSE); (FALSE); (FALSE); (FALSE); (FALSE); (FALSE); (FALSE); (FALSE); (FALSE); } 第四章 系统运行 测试以及运行界面 程 序 主 界 面 测 试 测试 测试过程中要判断是否成功,要分析程序界面的变化和计算数据的结果是否正确以及各功能键是否能正常实用。(梯度不能实用) 测试系统:Windows 7 64位 测试工具:Visual Studio C++ (中文版) 总 结 经过多番测试,得出结论为设计的计算器能够完成功能描述内容中的全部功能。经过几个星期的VC++课程设计,我们顺利完成该课程设计,并收获良多。我们大体总结了以下几点: 基本功要过硬,不能马虎经常犯的小错误。提高自己找错纠错能力,通常错误总是那几种,多练习就熟练了。 要善于查找资料,提高自己的资料查询能力,要善于利用网络来获得知识,获得帮助。开始着手程序设计时,有些功能感觉无从下手,都不知道要干什么,这些问题这要找到相关的资料就会得到提示从而理解所要解决问题的大致方向。有了明确的目的,就可以发挥自己的头脑来完成它了。 要善于思考,程序中有些实现难点和最初完成程序时免不了的许多不足就需要自己根据代码认真思考来解决。只有这样才能纠正程序的不足,并使其更加人性化。 这次课程设计让我们学到了很多,不仅巩固了MFC程序设计知识,而且也培养了我们的动手能力,令我们的创造性思维得到拓展。期待今后有更多类似的锻炼机会。 通过这次课程设计,可以明显的感觉到它弥补了课程教学的和实验中知识的深度和广度方面的不足,也让我们进一步掌握了面向对象程序设计的基本方法和编程技巧,同时也巩固所学理论知识,似然花费了不止一点点的时间和精力,不过那确实挺值得的,既让我们认识到自己知识方面的缺陷,又培养了我独立分析问题、解决问题的能力。 课程设计是需要大量时间去动手练习才能体验到它的内涵的,同时还需要用心地投入,时间和情感花下去之后,的确感受到有所收获,增加了对编程的兴趣。通过这次课程设计,掌握了对话框的相关操作,也体会到书写代码一定要仔细,有时候一小点拼写错误会浪费很多调试程序的时间,再有一点就是要好好学习英语,对编程有很大帮助。总之,这次课程设计学到了很多,通过实践真正的做到了学有所用。 参考文献 [1] 郑阿奇,Visual C++实用教程(第三版),北京:电子工业出版社,2000 [2] 严华峰,Visual C++课程设计案例精编,北京:中国水利水电出版社,2002 因篇幅问题不能全部显示,请点此查看更多更全内容