课程设计一: 计算器
选题难以级别:A级
1.1 程序目的
实现计算器的功能。用户根据程序的提示,输入数字,选择要进行的计算,可以进行加、减、乘、除运算,简单的四则运算及其测试,开平方,华氏温度与摄氏温度之间的相互转换等运算。
1.2 程序内容
(1) 完善计算器程序,改为可对实数操作。
(2) 完善程序,改为多个操作数基本四则运算,遇到0为止。
(3) 增加函数,完成四则混合运算,注意算法要考虑运算符的优先级,增加相应的主菜单选项。
(4) 添加语句,使四则运算具有测试功能。使四则运算具有测试功能,即计算机能够自动出题,并要求用户计算的对错打分,要求十题为一个单元,加减运算时最高为两位数运算,乘法为两位数乘一位数,除法是两位数或三位数除一位数,且要求没有余数。
(5) 可扩充其功能。
1.3 源代码
//Copyright by abilitytao
//All right not reserved!!
#include <process.h>
#include <iostream.h>
#include <conio.h>
#include <stdlib.h>
#include <math.h>
#include <stack>//添加的头文件,用于进行后缀表达式计算操作;
#include <cstring>//添加的头文件,用于字符串处理;
#include <ctype.h>//添加的头文件,仅仅为了使用isdigit函数;
using namespace std;
struct formula
{
char numordigit[100];
};
///////////////////////////////////////////////////////////////////////////////////
int formulalen;
char temp[1000];
formula in[1000];
formula pos[1000];
double number1,number2,answer,val;
///////////////////////////////////////////////////////////////////////////////////
class oopcalc
{
public:
void calcadd();
void calcsub();
void calcdiv();
void calcmult();
void calcfartocel();
void calcceltofar();
void calcsroot();
void calcmixed();//添加函数,用于混合四则运算;
void test();//添加函数,用于测试;
void exitprog();
void menu();
void badinput();
private:
double add(double x, double y);
double sub(double x, double y);
double div(double x, double y);
double mult(double x, double y);
double fartocel(double x);
double celtofar(double x);
double sqroot(double x);
void intoin();//添加函数,用于将中缀表达式放入结构体数组,从而实现数字与运算符的分离;
void intopos();//添加函数,用于将中缀表达式转化成后缀表达式;
double calculate();//添加函数,用于计算后缀表达式;
};
void oopcalc::calcadd()
{
cout << "The Add Function\n";
cout << "First number: ";
cin >> number1;
cout << "Second number: ";
cin >> number2;
answer = add(number1,number2);
cout << number1 << " + " << number2 << " = " << answer << endl;
cout <<"===============================================================================\n";
cerr<< "Press any key to continue\n";
getch();
menu();
}
void oopcalc::calcsub()
{
cout << "The Subtract Function\n";
cout << "First number: ";
cin >> number1;
cout << "Second number: ";
cin >> number2;
answer = sub(number1,number2);
cout << number1 << " - " << number2 << " = " << answer << endl;
cout <<"===============================================================================\n";
cerr << "Press any key to continue\n";
getch();
menu();
}
void oopcalc::calcdiv()
{
cout << "The Divide Function\n";
cout << "First number: ";
cin >> number1;
cout << "Second number: ";
cin >> number2;
answer = div(number1,number2);
cout << number1 << " / " << number2 << " = " << answer << endl;
cout <<"===============================================================================\n";
cerr << "Press any key to continue\n";
getch();
menu();
}
void oopcalc::calcmult()
{
cout << "The Multiply Function\n";
cout << "First number: ";
cin >> number1;
cout << "Second number: ";
cin >> number2;
answer = mult(number1,number2);
cout << number1 << " x " << number2 << " = " << answer << endl;
cout <<"===============================================================================\n";
cerr << "Press any key to continue\n";
getch();
menu();
}
void oopcalc::calcfartocel()
{
cout << "The Farenheit to Celsius Function\n";
cout << "Enter a tempature in Farenheit: ";
cin >> number1;
answer = fartocel(number1);
cout << "The tempature in Celsius is " << answer << endl;
cout <<"===============================================================================\n";
cerr << "Press any key to continue\n";
getch();
menu();
}
void oopcalc::calcceltofar()
{
cout << "The Celsius to Farenheit Function\n";
cout << "Enter a tempature in Celsius: ";
cin >> number1;
answer = celtofar(number1);
cout << "The tempature in Farenheit is " << answer << endl;
cout <<"===============================================================================\n";
cerr << "Press any key to continue\n";
getch();
menu();
}
void oopcalc::calcsroot()
{
cout << "The Square Root Function\n";
cout << "First number: ";
cin >> number1;
answer = sqroot(number1);
cout << "The square root of " << number1 << " is " << answer << endl;
cout <<"===============================================================================\n";
cerr << "Press any key to continue\n";
getch();
menu();
}
void oopcalc::calcmixed()
{
cout<<"Please Input The Formula(You Can Use The '(' And ')'As Well)\n";
intoin();
intopos();
int i;
for(i=0;i<formulalen;i++)
cout<<in[i].numordigit;
cout<<'='<<calculate()<<endl;
cout <<"===============================================================================\n";
cerr << "Press any key to continue\n";
getch();
menu();
}
void oopcalc::test() //添加内容 简单四则运算的测试
{
cout<<"简单四则运算的测试\n:" ;
int i,a,b,c,e,g,h,m,sum=0 ;
for(i=0;i<10;i++)
{
a=rand()%100 ; //应用的函数rand()产生所需的随机数
b=rand()%100 ;
c=rand()%10 ;
g=a*c; //先使g=a*c,然后在case'3'中g/c以获得没有余数的除法
m=rand()%4 ;
switch((int)m)
{
case 0 :
cout<<a<<'+'<<b<<'=' ;
e=a+b ;
break ;
case 1 :
cout<<a<<'-'<<b<<'=' ;
e=a-b ;
break ;
case 2 :
cout<<a<<'*'<<c<<'=' ;
e=a*c ;
break ;
case 3 :
cout<<g<<'/'<<c<<'=' ;
e=g/c ;
break ;
}
cin>>h ;
if(h==e)
{
cout<<"正确,得十分!\n" ;
sum+=10 ;
}
else cout<<"不正确,不得分!\n" ;
}
cerr<<"十题中,答对:"<<sum/10<<"题"<<'\t'<<"得分:"<<sum<<'\n' ;
cerr<<"Press any key to continue\n" ;
getch();
menu();
}
void oopcalc::exitprog()
{
exit(-1);
}
void oopcalc::menu()
{
int input;
oopcalc a;
system("cls"); //执行系统命令:cls-清屏
cerr <<"=======================================MENU====================================\n";
cerr <<" * 1: Add two numbers * \n";
cerr <<" * 2: Subtract two numbers * \n";
cerr <<" * 3: Divide two numbers * \n";
cerr <<" * 4: Multiply two numbers * \n";
cerr <<" * 5: Convert Farenheit to Celsius * \n";
cerr <<" * 6: Convert Celsius to Farenheit * \n";
cerr <<" * 7: Find the square root of a number * \n";
cerr <<" * 8: Complex Caculation('+','-','*','/') * \n";
cerr <<" * 9: Test For You * \n";
cerr <<" * 0: Exit this program * ";
cerr <<"===============================================================================\n";
cerr <<"Choice:";
cin >> input;
cout <<"===============================================================================\n";
switch (input)
{
case 1: a.calcadd();
break;
case 2: a.calcsub();
break;
case 3: a.calcdiv();
break;
case 4: a.calcmult();
break;
case 5: a.calcfartocel();
break;
case 6: a.calcceltofar();
break;
case 7: a.calcsroot();
break;
case 8: a.calcmixed();
break;
case 9: a.test();
break;
case 0: a.exitprog();
break;
default:a.badinput();
}
}
void oopcalc::badinput()
{
cout << "BAD INPUT!\n";
cout << "Press any key to continue\n";
getch();
menu();
}
double oopcalc::add(double x, double y)
{
val = x + y;
return val;
}
double oopcalc::sub(double x, double y)
{
val = x - y;
return val;
}
double oopcalc::div(double x, double y)
{
val = x / y;
return val;
}
double oopcalc::mult(double x, double y)
{
val = x * y;
return val;
}
double oopcalc::fartocel(double x)
{
double cel = ((x - 32) * 5) / 9;
return cel;
}
double oopcalc::celtofar(double x)
{
double f;
f = x * 9 / 5 + 32;
return f;
}
double oopcalc::sqroot(double x)
{
double g = sqrt(x);
return g;
}
void oopcalc::intoin()
{
formulalen=0;
int templen;
int temlen;
char tem[100];
cin>>temp;
templen=strlen(temp);
int i;
int j;
j=0;
for(i=0;i<templen;i+=temlen)
{
if(isdigit(temp[i]))
{
sscanf(&temp[i],"%[^-^+^*^/^(^)]",tem);
temlen=strlen(tem);
strcpy(in[j].numordigit,tem);
formulalen++;
j++;
}
else
{
temlen=1;
in[j].numordigit[0]=temp[i];
in[j].numordigit[1]='\0';
formulalen++;
j++;
}
}
}
void oopcalc::intopos()//这是用于将中缀表达式转化成后缀表达式的函数
{
/////////////////'(' ')''+''-''*''/''='
static int isp[7]={ 0,19,12,12,13,13,0};//为了编程方便,标记出各运算符的优先级;
static int icp[7]={20,19,12,12,13,13,0};//同上;
int precedence_sta;
int precedence_token;
stack<formula>sta;
int i;
int j;
char token[100];
formula start;
strcpy(start.numordigit,"\0");
sta.push(start);
j=0;
for(i=0;i<formulalen;i++)
{
strcpy(token,in[i].numordigit);
if(strcmp(token,"\0")==0)
break;
if(isdigit(token[0]))
{
strcpy(pos[j].numordigit,token);
j++;
}
else if(strcmp(token,")")==0)
{
while(strcmp(sta.top().numordigit ,"(")!=0)
{
strcpy(pos[j].numordigit,sta.top().numordigit);
j++;
sta.pop();
}
sta.pop();
}
else
{
if(strcmp(sta.top().numordigit,"(")==0)
precedence_sta=0;
if(strcmp(sta.top().numordigit,")")==0)
precedence_sta=19;
if(strcmp(sta.top().numordigit,"+")==0)
precedence_sta=12;
if(strcmp(sta.top().numordigit,"-")==0)
precedence_sta=12;
if(strcmp(sta.top().numordigit,"*")==0)
precedence_sta=13;
if(strcmp(sta.top().numordigit,"/")==0)
precedence_sta=13;
if(strcmp(sta.top().numordigit,"\0")==0)
precedence_sta=0;
if(strcmp(token,"(")==0)
precedence_token=20;
if(strcmp(token,")")==0)
precedence_token=19;
if(strcmp(token,"+")==0)
precedence_token=12;
if(strcmp(token,"-")==0)
precedence_token=12;
if(strcmp(token,"*")==0)
precedence_token=13;
if(strcmp(token,"/")==0)
precedence_token=13;
if(strcmp(token,"\0")==0)
precedence_token=0;
while(precedence_sta>=precedence_token)
{
pos[j]=sta.top();
j++;
sta.pop();
if(strcmp(sta.top().numordigit,"(")==0)
precedence_sta=0;
if(strcmp(sta.top().numordigit,")")==0)
precedence_sta=19;
if(strcmp(sta.top().numordigit,"+")==0)
precedence_sta=12;
if(strcmp(sta.top().numordigit,"-")==0)
precedence_sta=12;
if(strcmp(sta.top().numordigit,"*")==0)
precedence_sta=13;
if(strcmp(sta.top().numordigit,"/")==0)
precedence_sta=13;
if(strcmp(sta.top().numordigit,"\0")==0)
precedence_sta=0;
if(strcmp(token,"(")==0)
precedence_token=20;
if(strcmp(token,")")==0)
precedence_token=19;
if(strcmp(token,"+")==0)
precedence_token=12;
if(strcmp(token,"-")==0)
precedence_token=12;
if(strcmp(token,"*")==0)
precedence_token=13;
if(strcmp(token,"/")==0)
precedence_token=13;
if(strcmp(token,"\0")==0)
precedence_token=0;
}
strcpy(start.numordigit,token);
sta.push(start);
}
}
while(strcpy(token,sta.top().numordigit))
{
if(strcmp(token,"\0")==0)
break;
pos[j]=sta.top();
j++;
sta.pop();
}
strcpy(pos[j].numordigit,"\0");
}
double oopcalc::calculate()//这是用于后缀表达式计算的函数
{
stack<double>sta;
char token[100];
double result;
double op1;
double op2;
int i;
double tem;
for(i=0;i<=formulalen;i++)
{
strcpy(token,pos[i].numordigit);
if(strcmp(token,"\0")==0)
break;
if(isdigit(token[0]))
{
sscanf(token,"%lf",&tem);
sta.push(tem);
}
else
{
op2=sta.top();
sta.pop();
op1=sta.top();
sta.pop();
if(strcmp(token,"+")==0)
sta.push(op1+op2);
else if(strcmp(token,"-")==0)
sta.push(op1-op2);
else if(strcmp(token,"*")==0)
sta.push(op1*op2);
else if(strcmp(token,"/")==0)
sta.push(op1/op2);
}
}
result=sta.top();
sta.pop();
return result;
}
////////////////////////////////////////////////
/////////////////以下是主程序///////////////////
void main()
{
oopcalc s;
s.menu();
}
1.4小结:
必须承认,C++课程设计并没有想像中的那么简单。在上个学期的c++的学习中,我们主要研究的是面向过程的程序设计,而这次的课程设计却需要我们用类来完成整个程序。所以,在设计过程中也遇到了不少的麻烦,尽管如此,我还是收益颇丰。
首先,我学会了面向对象程序设计的基本思想,并了解到许多面向对象程序设计的优点,让我的编程能力有了一个新的突破。比如说,类封装的特性让一个类成为一个独立的个体,使所有的函数都封装在其中,这对于程序员对整个程序的理解有非常大的帮助。在大型程序的设计过程中,如过还是使用以往C语言的设计风格,会使得整个程序变得极为冗长,难懂,会给给修改及维护程序带来诸多不便。而面向对象的设计理念则妥善的解决了这一问题。
其次,这次课程设计也让我见到并掌握了许多以前未曾见到过的c++程序功能,很多即使在ACM集训队里也未曾见过的头文件,如<process.h>,<ctype.h>,<conio.h>等等,使我进一步了解到c++底层的强大功能。这着实令人惊叹!
再次,通过这次课程设计,我掌握了许多算法,如深度优先搜索和广度优先搜索,quicksort,堆排序,树结构的便历,等等。
我想,这次的课程设计使我收益良多。在今后的时间里,我会继续不断的,深入的去研究c++的算法,数据结构,以及数论,图论和组合数学里的有关知识,争取成为南理工计算机专业的优秀毕业生。