课程设计一:                                                                               计算器
 
                                            选题难以级别: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++的算法,数据结构,以及数论,图论和组合数学里的有关知识,争取成为南理工计算机专业的优秀毕业生。