课程设计报告题目:计算表达式的值1.问题描述对于给定的一个表达式,表达式中可以包括常数、算术运行符(“+”、“-”、“*”、“/”)和括号,编写程序计算表达式的值。
基本要求:从键盘输入一个正确的中缀表达式,将中缀表达式转换为对应的后缀表达式,并计算后缀表达式的值。
对于表达式中的简单错误,能够给出提示,并给出错误信息;表达式中可以包括单个字母表示的变量。
测试数据:任意选取一个符合题目要求的表达式。
提高要求:(1)能够处理多种操作符。
(2)实现包含简单运算的计算器。
(3)实现一个包含简单运算和函数运算的计算器。
2.需求分析(1)软件的基本功能本软件实在win32工程下实现的带有界面和图标的功能较为齐全的计算器。
此计算器分三个方面进行计算,分别为数值表达式的计算,字母表达式的计算和函数计算。
可由键盘或用鼠标点击按键输入带有数字或字母的中缀表达式,程序可以将输入的带有数字或字母的中缀表达式转换成对应的后缀表达式,并计算只含有数字的后缀表达式的值。
本软件支持含小数、多位数等多种操作数的处理,可以计算含加、减、乘、除、百分号、求余、求幂,求阶乘,求三角函数的值等多种运算符和函数的表达式(2)输入/输出形式用户可通过打开图标弹出来的计算器界面任意点击操作。
对于在输入时发生的简单错误,软件通过弹出对话框给出提示并且在提示错误的同时自动将用户的出错输入略去转化成正确的表达式进行计算,用户也可选择清楚操作然后重新输入a.对于数值和函数表达式软件会输出其表达式的后缀表达式和计算结果并保留六位小数;b.对于字母表达式因字母无法进行数值运算,软件仅输出其后缀表达式的值;清楚按钮可以清楚有已经输入或输出的数据从头计算;软件窗口可实现最小化。
并且输入编辑框可进行修改,复制,粘贴等操作,但后缀表达式和求值结果的编辑框中的内容不可修改,只能执行复制操作。
(3)测试数据要求用户可以输入一个符合要求的中缀表达式,也可以输入一个包含简单错误的表达式。
表达式中可以包括各种类型的常数以及字母等,操作符包括(+、-、*、/、%、^、!、sin、cos、tan、mod,pi)等,同时表达式还可以包括各种括号和三角函数。
3.概要设计(1)抽象数据类型根据题目的要求,本程序对所有输入的内容全部存储到字符数组中,考虑到将中缀表达式转换成后缀表达式和后缀表达式求值时需要用到栈,所以本程序定义了字符栈和数据栈,并定义了表达式的类,将对表达式的操作全部在类中进行。
最后将将所有的数据类型以及核心算法操作包含在头文件hanshu.h中,程序开始时通过调用此头文件执行操作。
a.字符栈数据类型:class CStack功能:1.取栈顶元素2.栈顶元素出栈3.元素入栈4.判断栈是否为空(空返回1否则返回0)栈中存储的元素类型必须是字符型b.浮点型数据栈类型:class DStack功能:1.取栈顶元素2.栈顶元素出栈3.元素入栈4.判断栈是否为空(空返回1否则返回0)栈中存储的元素类型必须是浮点型c.对表达式进行处理的类:class Expression主要功能:1.将中缀表达式转化成后缀表达式,数字,运算符两两之间加空格2.后缀表达式求值3.三角函数求值(2)主程序流程(3)模块调用关系本软件的函数包括:a.WinMain函数:软件的主函数,用于调用对话框b.DialogProc函数:计算器对话框的消息回调函数,用于接收和处理按键操作c.Power函数:求某个数值任意幂的函数d.Factorial函数:求阶乘函数数据类型:CStack字符栈;DStack浮点型数据栈;Expression对表达式进行处理的类。
其中Power函数和Factorial函数还有所有的数据类型和算法都包含在定义的hanshu.h的头文件中,在WinMain函数中的DialogProc函数中调用。
资源文件:a.Dialog资源:对话框资源文件b.Icon资源:图标资源文件结构关系如下:4.详细设计(1)界面设计如图所示界面,创建按钮并为每个控件创建ID号控件ID:(2)实现概要设计的数据类型CStack字符栈;class CStack{private:char datasta[100];int top;public:CStack(){top=-1;}char Pop(){return datasta[top--];}char Get(){return datasta[top];}void Push(char x){datasta[++top]=x;}int IsEmpty(){if(top==-1)return 1;else return 0;} };DStack浮点型数据栈;class DStack{private:double datasta[100];int top;public:DStack(){top=-1;}double Pop(){return datasta[top--];}double Get(){return datasta[top];}void Push(double x){datasta[++top]=x;}int IsEmpty(){if(top==-1)return 1;else return 0;}};Expression对表达式进行处理的类class Expression{private:char InArr[1024];DStack dsta;CStack csta;char arr[20];public:char AfterArr[1024];Expression(){}void get(char preArr[]){strcpy(InArr,preArr);}int CaseDetermine();void InfixToSuffix();double SuffixExpressionEvaluation ();double TrigonometricFunction();~Expression(){}};(3)主程序:实现对话框调用和资源加载int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow){DialogBox(hInstance,(LPCTSTR)IDD_DIALOG1,NULL,DialogProc);return 0;}(4)它模块的算法描述。
DialogProc函数:对按钮消息先进行截获,然后调用函数进行处理BOOL CALLBACK DialogProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)头文件hanshu.h:包含中缀转换成后缀和后缀求值的算法5.编码与调试分析(1)问题:由于用到栈的数据结构,在两个连续的优先级相同的运算符时,如2*3/5程序会先计算除法再计算乘法,这显然是错误的。
解决办法:碰到优先级相同的运算符时,交换运算符的出栈顺序,使上式达到先计算乘法再计算除法的目的。
(2)问题:由于向计算器输入的表达式全都是以字符的形式存储,在计算sin,cos,tan等有多个字符的函数时,程序不易识别。
解决办法:在程序存储信息时,将sin,cos,tan用每个函数的开头字母的大写形式的单个函数代替该函数,函数将会被容易识别。
(3)问题:无法处理多位数或多位小数解决办法:将小数点一起读入到字符串中,并在中缀表达式转换成后缀表达式时使运算符与运算符之间、数字与运算符之间、数字与数字之间、字母与字母之间、字母与运算符之间全部用空格隔开以便于区分。
6.使用说明打开快捷方式后弹出计算器界面1.点击计算类型(数值表达式、字母表达式、函数运算)2.点击按钮(或键盘)输入表达式3.点击等号得出结果4.点击“清除”按钮对上一次输入和计算结果进行清空5.点击“退出”关闭计算器7.测试结果准备典型的测试数据和测试方案,包括正确的输入及输出结果和含有错误的输入及输出结果。
(1)含小数、多位数、及括号的表达式显示结果(2)求余、求幂含百分号的表达式的显示结果(3)sin,cos,tan等三角函数的求值结果(4)对于错误输入的处理8.自学知识自主学习了哪些新知识及主要知识点描述。
在算法设计上自学了如何利用atof函数将字符型数据转化成浮点型数据以及如何判断字母大小写,这些都是比较容易的,这次课程设计主要自学经历在设计界面方面,通过查阅书籍资料,了解了win32编程的基本语法和用途,并根据以上自学知识设计出了计算器的界面。
9.课程设计心得体会通过这次课程设计让我了解到多大的程序都不可怕,任何陌生的东西也都不可怕,只要不去惧怕惊下心来去研究,不去急躁总能有所收获。
就像我之前对于界面设计一点都不了解,对win32,MFC编程更不了解,但因为需要逼自己必须在短时间内学习这些的时候这些困难就慢慢地迎刃而解了。
这次课设也给了我挑战和探索新知识的勇气和信心。