计算器 c语言课程设计
设计分析:
我做的是一个计算器程序,属于B级。题目要求如下:
1、完善计算器程序,改为可对实数操作。
2、完善程序,改为多个操作数基本四则运算,遇到z为止。
3、增加函数,完成四则混合运算,增加相应的主菜单选项
4、添加语句,使四则运算具有测试功能。
5、可扩充其功能。
所给的计算器源程序中已有基本的加、减、乘、除和开方运算,我所要做的就是添加一个可以进行四则混合运算功能的类。
本程序所要用到的头文件有如下几种:process,iostream,conio,stdlib,math和assert.
原程序中已经定义了加、减、乘、除和开方的运算,它用了类oopcalc将这几个基本运算进行封装。类中包含以下几个函数:void calcadd();
void calcsub();
void calcdiv();
void calcmult();
void calcfartocel();
void calcceltofar();
void calcsroot();
void exitprog();
void menu();
void badinput();
每个函数的参数形式如下:
int add(float x,float y);
int sub(float x, float y);
int div(float x, float y);
int mult(float x, float y);
int fartocel(float x);
int celtofar(float x);
int sqroot(float x);
原程序对这几个函数分别做了如下定义:int oopcalc::add(float x, float y)
{
val = x + y;
return val;
}
int oopcalc::sub(float x,float y)
{
val = x - y;
return val;
}
int oopcalc::div(float x, float y)
{
return val;
}
int oopcalc::mult(float x, float y) {
val = x * y;
return val;
}
int oopcalc::fartocel(float x)
{
int cel = ((x - 32) * 5) / 9;
return cel;
}
int oopcalc::celtofar(float x)
{
int f;
f = x * 9 / 5 + 32;
return f;
}
int oopcalc::sqroot(float x)
{
int g = sqrt(x);
}
首先要把程序改为可对实数进行操作,由于原程序中的操作数类型都是整形,因此我所采用的办法就是把“int”依次改成“float”。这是最简单的修改办法,也是最有效的修改办法。
在menu()函数中使用了switch()语句来对功能进行选择,以便于操作。不同的数字则对应不同的功能。
下面所要进行的修改就是添加四则运算功能。
首先在switch()语句中添加一个新的选项,以用于作为进行四则运算的入口。然后设计一个简单的计算器类,增加四则运算功能。
简单的运算只要求有两个操作数,如原程序中的加、减、乘除。而所增加的四则运算则要求输入多个操作数,有计算机自己通过程序来解决多个数字的运算。这就要求设计的程序能够自动辨别“+”,“-”,“*”,“/”的优先级和结合性。在这里,我运用了栈的功能进行对程序的修改。
设有表达式:
a+b*c-d/e=
为实现运算符的优先级,采用两个栈:一个数栈,一个运算符栈。数栈暂时存放操作数,运算符栈暂时存放运算符。从左向右扫描算术表达式,遇到操作数,压入数栈;遇到运算符,则与运算符栈栈顶的运算符比较优先级。若新的运算符优先级高或运算符栈空,则压栈;否则,将栈顶运算符出栈,与数字栈出栈的两个数据进行运算,结果
压入数栈,再将新运算符压栈。继续扫描,直到遇到=号,扫描结束。栈中数据继续按前面规则出栈。上面所列表达式运算过程如下图所示:
(A)(B)(C)(D)(E)
N O N O N O N O N O
- - - - - - - - - -
- - - - - - - - - -
- - —> e - --> - - --> - - --> - -
c - b*c->t1
d / d/e->t2 t2 - t1-t2->t3 - - a+t3->t4 - -
b * t1 _ t1 _ t3 - - -
a + a + a + a + - -
首先a入数栈,“+”入运算符栈,b入数栈,“*”入运算符栈,c入数栈,见图(A);再扫描到“-”号,则“*”和c、b出栈,b*c得t1压入数栈,“-”号压入运算符栈,“/’号压入运算符栈,e压入数栈,遇到=,
扫描结束,见图(B);”/“号弹出运算符栈,e、d弹出数栈,d/e得t2压数栈,见图C;”-“号出栈,t2、t1出栈,t1-t2得t3、t4压栈,见图(D);”+“号出栈,t3、a出栈,栈全空,a+t3得t4,即运算结果。
增加四则混合运算的功能要解决的问题是怎样使计算机能分辨出运算符的优先级。这里我想到了我们上课学的栈和链表的知识这题我用到了链栈。首先建立一个链栈的类模板和一个结点链表。
template
这一行是类结点的声明。因为在类中也同样遵循“先声明后使用”的原则。
template
T info;
Node
public:
Node(T data=0,Node
{
info=data;
link=next;
}
friend class Stack
};
这一段是结点模板的定义。Info是结点,“Node
Stack。“info=data;”设置第一个接点的值,“link=next;”把下一个指针的值赋给link指针。
template
Node
public:
Stack(){top=NULL;}
~Stack();
void Push(const T &data);
T Pop();
T GetTop();
void MakeEmpty();
bool IsEmpty(){return top==NULL;}
};
这一段是类模板的定义。其中“Node
Node
while(top!=NULL){temp=top;top=top->link;delete temp;}
}
这一段是对清空链表的函数进行定义。设置了一个指针temp,当头结点不等于NULL是进行while循环。循环是将头结点的值赋给temp,再把头结点的指针指向下一个结点。
template
}
链栈向前生成,新压栈的结点在链栈头
template
assert(!IsEmpty());
Node
T data=temp->info;
top=top->link;
delete temp;
return data;
}
这是对弹出函数的定义。“top=top->link;”丢弃栈顶结点。“delete temp; ”释放栈顶结点。“return data; ”返回栈顶数据。
class Calculator{
Stack
Stack
public:
Calculator(void){};