实验四 类和对象(二)

一、目的要求
1.理解面向对象的程序设计的特点;
2.学会构造函数的使用和函数重载;
3.学会对象指针的使用、对象的动态建立和释放;
4.理解类的封装性和信息隐藏、析构函数的作用。
二、实验内容:
1.定义学生类,包括学号、姓名、性别、成绩,学生分为两类,课程门数不同,并将课程成绩全部初始化为0;假设有n个学生,由键盘输入学生信息;
2.定义类成员函数,完成修改学生的信息,统计所有学生课程的平均成绩、最高分和最低分;
3.同时输出所有学生信息;
4.通过输入学生学号或姓名查询某学生的信息。
三、实验要求:
1.利用头文件和多个源文件分别实现类的声明、类成员函数的定义和主函数;
2.从键盘输入学生数,为对象动态分配内存空间,并保证对象使用完毕时释放内存空间;
3.定义构造函数完成类成员变量的初始化;
4.利用静态成员变量与静态成员函数统计所有学生课程的平均成绩、最高分和最低分;
5.利用函数的重载实现通过输入学生学号或姓名查询某学生的信息。
兼顾程序的逻辑性、人性化设计,并减少冗余代码,(比如输入时提示输入内容、输出格式一目了然等。
附代码
!!!编译环境 DevC++ 5.11 TDM-GCC 4.9.2 64-Bit Release
头文件 iquery.h

#ifndef  _IQUERY_H
#define _IQUERY_H 1
    using namespace std;
    #define MAXN 100 
    #define MAXY 5

    class student{
        private:
            int old;
            string sex;            
            string name;
            int number; 
            double chinese;
            double math;
            double english;
            double science;   
            double art;       
            double ave_grade;        //个人主科综合成绩 

            static double sum_1[MAXY];
            static int count_1;
            static double max_allgrade_1[MAXY];
            static double min_allgrade_1[MAXY]; 

            static double sum_2[MAXY];
            static int count_2;
            //第一类 存储平均值和最大最小值的数组 
            static double ave_allgrade_1[MAXY];
            static double max_1[MAXY];
            static double min_1[MAXY];
            //第二类 
            static double ave_allgrade_2[MAXY];
            static double max_2[MAXY];
            static double min_2[MAXY];
    public: 
        void data_input(int idx); 
        bool data_grade_judge();    //judge 每个学生成绩是否及格 
        void data_output(int idx);
        //查找函数 
        bool data_search(string pname)const;//重载实现姓名或学号查找   int data_search(int *pnumber);
        bool data_search(int pnumber)const;
        //析构 
        ~student();
        //计算平均数 
        static double data_ave_allgrade(int idx);

        //输出静态变量,实现静态成员封装 
        static double output_ave_allgrade(int idx);
        static double output_max_allgrade(int idx);
        static double output_min_allgrade(int idx);

        //total函数
        void total(int idx);

        //找最大最小 
        void judge_max(int idx);
        void judge_min(int idx);
        void init_judge_min(int idx);             //min数组第一次调用时初始化
        //修改
        void data_change(); 
    };

#endif
//  类成员函数中const的使用
//  一般放在函数体后,形如:void   fun()   const;     
//    任何不会修改数据成员的函数都因该声明为const类型。

头文件实现文件 iquery,cpp

#include <iostream>
#include "string"
#include "iquery.h"
#include "iomanip"
using namespace std; 
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
void student :: data_input(int idx){
    if(idx==1){
        cout<<"    姓名:" ;cin>>name;
        cout<<"    年龄:" ;cin>>old; 
        cout<<"    性别:" ;cin>>sex;
        cout<<"    学号:" ;cin>>number;
        cout<<"接下来依次输入语文,数学,英语,科学成绩"<<endl;
        cin>>chinese>>math>>english>>science;
        ave_grade=(math+chinese+english)/3;
    }
    else if(idx==2){
        cout<<"    姓名:" ;cin>>name;
        cout<<"    年龄:" ;cin>>old; 
        cout<<"    性别:" ;cin>>sex;
        cout<<"    学号:" ;cin>>number;
        cout<<"接下来依次输入语文,数学,英语,科学,艺术成绩"<<endl;
        cin>>chinese>>math>>english>>science>>art;
        ave_grade=(math+chinese+english)/3;
    }else{
        cout<<"error in student choice, only 1 or 2"<<endl;
    }
}
bool student :: data_grade_judge(){
    while(chinese<90||math<90||english<90){
        return 1;
    }
    return 0;   
}
void student :: data_output(int idx){
    if(idx==1){
        cout<<setiosflags(ios::left);
        cout<<"    姓名:" <<name<<endl;
        cout<<"    年龄:" <<old<<endl;
        cout<<"    性别:" <<sex<<endl;
        cout<<"    学号:" <<number<<endl;
        cout<<setw(10)<<"    语文:" <<setw(6)<<chinese<<setw(6)<<"数学:"<<setw(6)<<math<<setw(6)<<"英语:"<<setw(6)<<english<<endl;
        cout<<setw(10)<<"    科学:"<<setw(6)<<science <<endl;
        cout<<"    主科平均成绩:"<<ave_grade<<endl; 
    }
    else if(idx==2){
            cout<<setiosflags(ios::left);
        cout<<"    姓名:" <<name<<endl;
        cout<<"    年龄:" <<old<<endl;
        cout<<"    性别:" <<sex<<endl;
        cout<<"    学号:" <<number<<endl;
        cout<<setw(10)<<"    语文:" <<setw(6)<<chinese<<setw(6)<<"数学:"<<setw(6)<<math<<setw(6)<<"英语:"<<setw(6)<<english<<endl;
        cout<<setw(10)<<"    科学:"<<setw(6)<<science <<setw(6)<<"艺术:"<<setw(6)<<art<<endl;
        cout<<"    主科平均成绩:"<<ave_grade<<endl; 
    }else{
        cout<<"error in student choice, only 1 or 2"<<endl;
    }

}
bool student :: data_search(string pname) const {
    if(this->name.compare(pname)==0)
    return 1;
    else return 0;
}
bool student :: data_search(int  pumber) const {
    if(pumber==this->number)
    return 1;
    else return 0;
}
//静态成员变量初始化  类一 
int  student::count_1=0;
double student::sum_1[MAXY]={0,0,0,0,0};
double student::max_1[MAXY]={0,0,0,0,0};
double student::min_1[MAXY]={0,0,0,0,0};
double student::ave_allgrade_1[MAXY]={0,0,0,0,0};
//类二 
int  student::count_2=0;
double student::sum_2[MAXY]={0,0,0,0,0};
double student::max_2[MAXY]={0,0,0,0,0};
double student::min_2[MAXY]={0,0,0,0,0};
double student::ave_allgrade_2[MAXY]={0,0,0,0,0};

double student :: output_ave_allgrade(int idx){
    switch(idx){
        case 10:
            return ave_allgrade_1[0];
        case 11:
            return ave_allgrade_1[1];
        case 12:
            return ave_allgrade_1[2];
        case 13:
            return ave_allgrade_1[3];
        //类2    
        case 20:
            return ave_allgrade_2[0];
        case 21:
            return ave_allgrade_2[1];
        case 22:
            return ave_allgrade_2[2];
        case 23:
            return ave_allgrade_2[3];
        case 24:
            return ave_allgrade_2[4];
        default:
            cout<<"error in ave_allgrade choice, only 10 11 12 13 or 20 21 22 23 24"<<endl;
    }
}
double student :: output_max_allgrade(int idx){
    switch(idx){
        case 10:
            return max_1[0];
        case 11:
            return max_1[1];
        case 12:
            return max_1[2];
        case 13:
            return max_1[3];
        //类2    
        case 20:
            return max_2[0];
        case 21:
            return max_2[1];
        case 22:
            return max_2[2];
        case 23:
            return max_2[3];
        case 24:
            return max_2[4];
        default:
            cout<<"error in ave_allgrade choice, only 10 11 12 13 or 20 21 22 23 24"<<endl;
        }
}
double student :: output_min_allgrade(int idx){
    switch(idx){
        case 10:
            return min_1[0];
        case 11:
            return min_1[1];
        case 12:
            return min_1[2];
        case 13:
            return min_1[3];
        //类2    
        case 20:
            return min_2[0];
        case 21:
            return min_2[1];
        case 22:
            return min_2[2];
        case 23:
            return min_2[3];
        case 24:
            return min_2[4];
        default:
            cout<<"error in ave_allgrade choice, only 10 11 12 13 or 20 21 22 23 24"<<endl;
        }
}

void student :: total(int idx){
    if(idx==1){
        sum_1[0]+=chinese;
        sum_1[1]+=math;
        sum_1[2]+=english;
        sum_1[3]+=science; 
        count_1++;
    }
    else if(idx==2){
        sum_2[0]+=chinese;
        sum_2[1]+=math;
        sum_2[2]+=english;
        sum_2[3]+=science; 
        sum_2[4]+=art; 
        count_2++; 

    }else{
        cout<<"error in student choice, only 1 or 2"<<endl;
    }

}
double student :: data_ave_allgrade(int idx){
    if(idx==1){
        ave_allgrade_1[0]=sum_1[0]/(count_1);
        ave_allgrade_1[1]=sum_1[1]/(count_1);
        ave_allgrade_1[2]=sum_1[2]/(count_1);
        ave_allgrade_1[3]=sum_1[3]/(count_1);
    }
    else if(idx==2){
        ave_allgrade_2[0]=sum_2[0]/(count_2);
        ave_allgrade_2[1]=sum_2[1]/(count_2);
        ave_allgrade_2[2]=sum_2[2]/(count_2);
        ave_allgrade_2[3]=sum_2[3]/(count_2);
        ave_allgrade_2[4]=sum_2[4]/(count_2);
    }else{
        cout<<"error in student choice, only 1 or 2"<<endl;
    }

}
void student :: judge_max(int idx){
    if(idx==1){
        if(max_1[0]<this->chinese) 
        max_1[0]=this->chinese;
        if(max_1[1]<this->math) 
        max_1[1]=this->math;
        if(max_1[2]<this->english) 
        max_1[2]=this->english;
        if(max_1[3]<this->science) 
        max_1[3]=this->science;
    }
    else if(idx==2){
        if(max_2[0]<this->chinese) 
        max_2[0]=this->chinese;
        if(max_2[1]<this->math) 
        max_2[1]=this->math;
        if(max_2[2]<this->english) 
        max_2[2]=this->english;
        if(max_2[3]<this->science) 
        max_2[3]=this->science;
        if(max_2[4]<this->art)
        max_2[4]=this->art;
    }else{
        cout<<"error in student choice, only 1 or 2"<<endl;
    }

}
void student :: judge_min(int idx){
    if(idx==1){
        if(min_1[0]>this->chinese) 
        min_1[0]=this->chinese;
        if(min_1[1]>this->math) 
        min_1[1]=this->math;
        if(min_1[2]>this->english) 
        min_1[2]=this->english;
        if(min_1[3]>this->science) 
        min_1[3]=this->science;
    }
    else if(idx==2){
        if(min_2[0]>this->chinese) 
        min_2[0]=this->chinese;
        if(min_2[1]>this->math) 
        min_2[1]=this->math;
        if(min_2[2]>this->english) 
        min_2[2]=this->english;
        if(min_2[3]>this->science) 
        min_2[3]=this->science;
        if(min_2[4]>this->art)
        min_2[4]=this->art;
    }else{
        cout<<"error in student choice, only 1 or 2"<<endl;
    }

}
void student :: init_judge_min(int idx){
    if(idx==1){
        min_1[0]=this->chinese;
        min_1[1]=this->math;
        min_1[2]=this->english;
        min_1[3]=this->science; 
    }
    else if(idx==2){
        min_2[0]=this->chinese;
        min_2[1]=this->math;
        min_2[2]=this->english;
        min_2[3]=this->science; 
        min_2[4]=this->art;
    }else{
        cout<<"error in student choice, only 1 or 2"<<endl;
    }

}
void student :: data_change(){
    int cnt;
    int grade_change;
    cout<<"修改成绩,请输入对应位置"<<endl;
    cin>>cnt;
    switch(cnt){
        case 1:
            cout<<"请输入修改后的chinese成绩"<<endl;
            cin>>grade_change;this->chinese =grade_change;
            break;
        case 2:
            cout<<"请输入修改后的math成绩"<<endl;
            cin>>grade_change;this->math =grade_change;
            break;
        case 3:
            cout<<"请输入修改后的english成绩"<<endl;
            cin>>grade_change;this->english =grade_change;
            break;
        default :
            cout <<"error in fun_data_change" ;
    }

}
//析构函数 
student::~student()
{
    cout<<endl<<"thank you for use,written by chenfeng."<<endl<<"all right reserved";
}   

源码 main.cpp

#include <iostream>
#include "iquery.h"
#include "string"
#include "iomanip"
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
int main(int argc, char** argv) {
    int num1,num2;
    int cnt=0; 
    string search;
    int psearch; 

    cout<<"请注意学生共有两类,请分别输入两类学生的信息。"<<endl;
    cout<<"请输入第一类学生人数:"<<endl;
    cin>>num1;
    cout<<"请输入第二类学生人数:"<<endl; 
    cin>>num2;
    student *stu1=new student[num1];
    student *stu2=new student[num2];

    system("cls");

    cout<<"--------------------输入第一类学生信息--------------------"<<endl;
    for (int i=0;i<num1;i++)
    {
        stu1[i].data_input(1);
    }
    cout<<"--------------------输入第二类学生信息--------------------"<<endl;
    for (int i=0;i<num2;i++)
    {
        stu2[i].data_input(2);
    }
    cout<<"信息输入结束"<<endl;

    getchar(); 
    system("cls");
    cout<<setiosflags(ios::left);
    //对数据进行处理
    //计算平均值
    for(int i=0;i<num1;i++){
        stu1[i].total(1);
    } 
    student :: data_ave_allgrade(1);
    for(int i=0;i<num2;i++){
        stu2[i].total(2);
    } 
    student :: data_ave_allgrade(2);
    //计算最大最小值 
    stu1[0].init_judge_min(1);
    for(int i=0;i<num1;i++){
        stu1[i].judge_max(1);
        stu1[i].judge_min(1);
    } 
    stu2[0].init_judge_min(2);
    for(int i=0;i<num2;i++){
        stu2[i].judge_max(2);
        stu2[i].judge_min(2);
    } 
        //输出成绩数据 
    cout<<"------------------所有课程成绩统计------------------------"<<endl;
    cout<<"第一类"<<endl; 
    cout<<"课程      平均分      最高分      最低分" <<endl;
    cout<<"语文      "<<setw(12)<<student::output_ave_allgrade(10)<<setw(12)<<student::output_max_allgrade(10)<<setw(12)<<student::output_min_allgrade(10)<<endl;
    cout<<"数学      "<<setw(12)<<student::output_ave_allgrade(11)<<setw(12)<<student::output_max_allgrade(11)<<setw(12)<<student::output_min_allgrade(11)<<endl;
    cout<<"英语      "<<setw(12)<<student::output_ave_allgrade(12)<<setw(12)<<student::output_max_allgrade(12)<<setw(12)<<student::output_min_allgrade(12)<<endl;
    cout<<"科学      "<<setw(12)<<student::output_ave_allgrade(13)<<setw(12)<<student::output_max_allgrade(13)<<setw(12)<<student::output_min_allgrade(13)<<endl;
//  cout<<"艺术      "<<setw(12)<<student::output_ave_allgrade(14)<<setw(12)<<student::output_max_allgrade(14)<<setw(12)<<student::output_min_allgrade(14)<<endl<<endl; 
    cout<<"第二类"<<endl; 
    cout<<"课程      平均分      最高分      最低分" <<endl;
    cout<<"语文      "<<setw(12)<<student::output_ave_allgrade(20)<<setw(12)<<student::output_max_allgrade(20)<<setw(12)<<student::output_min_allgrade(20)<<endl;
    cout<<"数学      "<<setw(12)<<student::output_ave_allgrade(21)<<setw(12)<<student::output_max_allgrade(21)<<setw(12)<<student::output_min_allgrade(21)<<endl;
    cout<<"英语      "<<setw(12)<<student::output_ave_allgrade(22)<<setw(12)<<student::output_max_allgrade(23)<<setw(12)<<student::output_min_allgrade(22)<<endl;
    cout<<"科学      "<<setw(12)<<student::output_ave_allgrade(23)<<setw(12)<<student::output_max_allgrade(23)<<setw(12)<<student::output_min_allgrade(23)<<endl;
    cout<<"艺术      "<<setw(12)<<student::output_ave_allgrade(24)<<setw(12)<<student::output_max_allgrade(24)<<setw(12)<<student::output_min_allgrade(24)<<endl;


    cout<<"----------------------所有学生信息------------------------"<<endl;
    cout<<"第一类学生"<<endl;
    for(int i=0;i<num1;i++){
        stu1[i].data_output(1);
        cout<<endl;
    } 
    cout<<"第二类学生"<<endl; 
    for(int j=0;j<num2;j++){
        stu2[j].data_output(2);
        cout<<endl;
    }

    cout<<"-------------------------信息查询------------------------"<<endl;
    cout<<"请注意:查询既可以使用姓名也可以使用学号,但使用姓名可能出现重名情况。" <<endl;
    do{
        cout<<"请输入查询姓名或学号:"<<endl;
        cout<<"    查询姓名,输入1"<<endl;
        cout<<"    查询学号,输入2"<<endl;
        cin>>psearch;
        if(psearch==1){
            cout<<"请输入要查询的学生姓名:"<<endl; 
            cin>>search; 
            for(int i=0;i<num1;i++){
                if(stu1[i].data_search(search)){
                    stu1[i].data_output(1); 
                }
            }
            for(int j=0;j<num2;j++){
                if(stu2[j].data_search(search)){
                    stu2[j].data_output(2);
                }
            }
            fflush(stdin); 
            cout<<"你想修改该成员信息么?"<<"输入1,需要"<<"输入2,不需要"<<endl<<"没有输出结果请忽略该提示"<<endl;
            cin>>psearch;
            if(psearch==1) {
                for(int i=0;i<num1;i++){
                    if(stu1[i].data_search(search)){
                        stu1[i].data_change();
                    }
                }
                for(int j=0;j<num2;j++){
                    if(stu2[j].data_search(search)){
                        stu2[j].data_change();
                    }
                }

            }
        }
        if(psearch==2){
            cout<<"请输入要查询的学生学号:"<<endl; 
            cin>>psearch; 
                for(int i=0;i<num1;i++){
                if(stu1[i].data_search(psearch)){
                    stu1[i].data_output(1); 
                }
            }
            for(int j=0;j<num2;j++){
                if(stu2[j].data_search(psearch)){
                    stu2[j].data_output(2);
                }
            }
            fflush(stdin); 
            cout<<"你想修改该成员信息么?"<<"输入1,需要"<<endl<<"输入2,不需要";
            cin>>psearch;
            if(psearch==1) {
                for(int i=0;i<num1;i++){
                    if(stu1[i].data_search(search)){
                        stu1[i].data_change();
                    }
                }
                for(int j=0;j<num2;j++){
                    if(stu2[j].data_search(search)){
                        stu2[j].data_change();
                    }
                }
            }
        }
        fflush(stdin);
        if(psearch==0){
            break;  
            }
        cout<<endl<<"如果没有输出结果,则无此学生信息"<<endl<<"你可重新输入1 or 2 进行查找"<<endl<<"输入0结束查询,程序退出"<<endl<<endl; 
    }while(psearch);




    cout<<"-------------------------使用结束------------------------"<<endl;    
    delete [] stu1;
    delete [] stu2;
    return 0;
}

注:
已经出现过的error:

  1. 静态成员变量在DevC++ 5.11 TDM-GCC 4.9.2 64-Bit Release 下需要手动初始化,并注意不要在头文件里进行初始化
  2. 静态成员函数只能操作或访问静态成员,不能访问非静态成员;非静态成员函数则两者都可以

存在的问题:

  1. 析构函数调用次数的问题:有时候调用一次,有时候是两次
  2. 输出时逻辑存在一定问题。

可行性优化:

  1. 功能通过菜单进行选择
  2. 调用构造函数进行对象的初始化
  3. 使用继承完成student类
  4. 使用linkedList优化数据结构
  5. 减少冗余代码
  6. student类数据的封装带来的接口的冗余怎么处理?

猜你喜欢

转载自blog.csdn.net/qq_40724028/article/details/80001785
今日推荐