1、程序员-C+程序设计(二)及答案解析(总分:100.00,做题时间:90 分钟)一、试题一(总题数:1,分数:15.00)阅读以下说明和 C+代码,填补 C+代码中的空缺,将解答写在对应栏内。说明已知某公司按周给员工发放工资,其工资系统需记录每名员工的员工号、姓名、工资等信息。其中一些员工是正式的,按年薪分周发放(每年按 52 周计算);另一些员工是计时工,以小时工资为基准,按每周工作小时数核算发放。下面是实现该工资系统的 C+代码,其中定义了 4 个类:工资系统类 PayRoll、员工类 Emplovee、正式工类 Salaried 和计时工类 Hourly,Salaried 和 Hourl
2、y 是 Employee 的子类。C+代码/头文件和域名空间略const int EMPLOYEE_NUM=5;class Employeeprotected:int emDCode; /员工号string name; /员工姓名double salary; /周发放工资public:Employee(const int empCode,const string name)this-empCode=empCode; this-name=name;virtualEmployee()virtual void pay()=0;double getSalary()return this-salary;
3、class Salaried _private: double payRate; /年薪public:Salaried(const int empCode,const string void pay()this-salary=_;/计算正式员工的周发放工资数coutthis-name“:“this-salaryendl;class Hourly _ private:double payRate; /小时工资数int hours; /周工作小时数public:Hourly(const int empCode, const string this-hours=hours,void pay()thi
4、s-saiary=_;/计算计时工的周发放工资数coutthis-name“:this-salaryendl;class PayRollpublic:void pay(Employee* e)for (int i=0; iEMPLOYEE_ NUM; i+)ei-pay();int main()PayRoll* payRoll=new PayRoll;_ employeesEMPLOYEE_ NUM=new Salaried(1001,“Zhang San“,58000.00),/此处省略对其他职工对象的生成new Hourly(1005,“L1“,12,50.00),;payRoll-pay
5、(_);double total=0.0;for(int i=0;iEMPLOYEE_ NUM;i+)(total+=employeesi-getSalary(); /统计周发放工资总额cout“总发放额=“totalendl;delete payRoll; retum 0;(分数:15.00)填空项 1:_填空项 1:_填空项 1:_填空项 1:_填空项 1:_填空项 1:_二、试题二(总题数:1,分数:15.00)阅读以下说明和 C+代码,填充代码中的空缺。说明下面的程序用来计算并寻找平面坐标系中给定点中最近的点对(若存在多对,则输出其中的一对即可)。程序运行时,先输入点的个数和一组互异的
6、点的坐标,通过计算每对点之间的距离,从而确定出距离最近的点对。例如,在图所示的 8 个点中,点(1,1)与(2,0.5)是间距最近的点对。(分数:15.00)填空项 1:_填空项 1:_填空项 1:_填空项 1:_填空项 1:_三、试题三(总题数:1,分数:15.00)阅读下列说明和 C+代码,填充代码中的空缺。说明某学校在学生毕业时要求对其成绩进行综合评定,学生的综合成绩(GPA)由其课程加权平均成绩(Wg)与附加分(Ag)构成,即 GPA=Wg+Ag。设一个学生共修了 n 门课程,则其加权平均成绩(Wg)定义如下:其中,gradei、Ci 分别表示该学生笫 i 门课程的百分制成绩及学分。学
7、生可以通过参加社会活动或学科竞赛获得附加分(Ag)。学生参加社会活动所得的活动分(Apoints)是直接给出的,而竞赛分(Awards)则由下式计算(一个学生最多可参加 m 项学科竞赛):(分数:15.00)填空项 1:_填空项 1:_填空项 1:_填空项 1:_填空项 1:_填空项 1:_四、试题四(总题数:1,分数:15.00)阅读以下说明和 C+代码,将应填入_处的语句或语句成分写在对应栏内。说明某数据文件 students.txt 的内容为 100 名学生的学号和成绩,下面的程序将文件中的数据全部读入对象数组,按分数从高到低进行排序后选出排名前 30%的学生。C+代码#include
8、iostream#include fstream#include stringusing namespace std;class Studentprivate:string sNO; /学号int credit;/分数public:Student(string a,int b)sNO=a;credit=b;Student()int getCredit();void out();_:getCredit()return credit;_:out()Cout“SNO:“sNO“,Credit=“creditendl;class SortStudentpublic:void sort(Student
9、*s,int n);SortStudent();void SortStudent:sort(Student *s,int n)for(int i=0;in-1;i+)for(int j=i+1;jn;j+)if(si._sj._Student temp=si;si=sj;sj=temp;int main(int argc,char* argv)const int number=100; /学生总数ifstream students;students.open(“students.txt“);if(!students.is open()throw 0;Student *testStudent=_
10、number;int k=0;string s;while(getline(students,s,/n)/每次读取一个学生的学号和成绩Student student(s.substr(0,s.find(,),atoi(s.substr(s.find(,)+1).c_str();testStudentk+=student;Students.closeo;_;ss.sort(testStudent,k);cout“top 30%:“+endl;for(k=0;knumber*0.3;k+)testStudentk.out();deletetestStudent;return 0;(分数:15.00
11、)填空项 1:_填空项 1:_填空项 1:_填空项 1:_填空项 1:_填空项 1:_五、试题五(总题数:1,分数:20.00)阅读以下说明和 C+代码,将应填入_处的字句写在对应栏内。说明现需要统计某企业员工的月平均工资,即该企业本月发给员工的工资总和除以员工数。假设企业本月发给员工的工资总和为 sumSalary,该企业的员工总数为 employeeNumber,下面的程序代码计算该企业员工本月的平均工资,其中需要处理 employNumber 为 0 的情况。C+代码#include iostreamusing namespace std;class Departmentprotecte
12、d:float average(float x,int y)if(y=0)throw _;return x/y;public:void caculate(void)float sumSalary;int employeeNumber;trycout“请输入当月工资总和与员工数:“endl;cinsumSalaryemployeeNumber;float k=average(sumSalary,employeeNumber);cout“平均工资:“kendl;_(int e)if(e=0)cout“请重新输入当月工资总和与员工数:“endl;cinsumSalaryemployeeNumber;
13、float k=average(sumSalary,employeeNumber);cout“平均工资:“kendl;void main()try _;d.caculate();_(int e)if(e=0)cout“程序未正确计算平均工资!“endl;程序运行时,若输入的员工工资总和为 6000,员工数为 5,则屏幕输出为:请输入当月工资总和与员工数:6000 5_若程序运行时,第一次输入的员工工资总和为 6000,员工数为 0,第二次输入的员工工资总和为 0,员工数为 0,则屏幕输出为:请输入当月工资总和与员工数:6000 0_0 0_(分数:20.00)填空项 1:_填空项 1:_填空项
14、 1:_填空项 1:_填空项 1:_六、试题六(总题数:1,分数:20.00)阅读以下说明和 C+代码,将应填入_处的字句写在对应栏内。说明已知类 LinkedList 表示列表类,该类具有 4 个方法:addElement()、lastElement()、numberOfElement()以及 removeLastElement()。4 个方法的含义分别如下。 void addElement(Obect):在列表尾部添加一个对象。 Object lastElement():返回列表尾部对象。 int numberOfElement():返回列表中对象的个数。 void removeLastE
15、lement():删除列表尾部的对象。现需要借助 LinkedList 来实现一个 Stack 栈类,C+代码 1 和 C+代码 2 分别采用继承和组合的方式来实现。C+代码 1Class Stack:public LinkedListpublic:void push(Object o)(addElement(o); /压栈Object peek()return _; /获取栈顶元素bool isEmpty() /判断栈是否为空return numberOfElement()=0;Object pop /弹栈Object o=lastElement();_;Return 0;C+代码 2cla
16、ss stackprivate:_;public:void push(Object o) /压栈list.addElement(o);object peek /获取栈顶元素return list _;bool isEmpty() /判断栈是否为空retum list.numberOfElement()=0;Object pop() /弹栈Objecto=list.lastElement();list.removeLastElement();return o;问题若类 LinkedList 新增加了一个公有的方法 removeElement(int index),用于删除列表中第 index个元
17、素,则在用继承和组合两种实现栈类 Stack 的方式中,哪种方式下 Stack 对象可访问方法removeElement(int index)?_(A继承 B组合)(分数:20.00)填空项 1:_填空项 1:_填空项 1:_填空项 1:_填空项 1:_程序员-C+程序设计(二)答案解析(总分:100.00,做题时间:90 分钟)一、试题一(总题数:1,分数:15.00)阅读以下说明和 C+代码,填补 C+代码中的空缺,将解答写在对应栏内。说明已知某公司按周给员工发放工资,其工资系统需记录每名员工的员工号、姓名、工资等信息。其中一些员工是正式的,按年薪分周发放(每年按 52 周计算);另一些员
18、工是计时工,以小时工资为基准,按每周工作小时数核算发放。下面是实现该工资系统的 C+代码,其中定义了 4 个类:工资系统类 PayRoll、员工类 Emplovee、正式工类 Salaried 和计时工类 Hourly,Salaried 和 Hourly 是 Employee 的子类。C+代码/头文件和域名空间略const int EMPLOYEE_NUM=5;class Employeeprotected:int emDCode; /员工号string name; /员工姓名double salary; /周发放工资public:Employee(const int empCode,cons
19、t string name)this-empCode=empCode; this-name=name;virtualEmployee()virtual void pay()=0;double getSalary()return this-salary;class Salaried _private: double payRate; /年薪public:Salaried(const int empCode,const string void pay()this-salary=_;/计算正式员工的周发放工资数coutthis-name“:“this-salaryendl;class Hourly
20、_ private:double payRate; /小时工资数int hours; /周工作小时数public:Hourly(const int empCode, const string this-hours=hours,void pay()this-saiary=_;/计算计时工的周发放工资数coutthis-name“:this-salaryendl;class PayRollpublic:void pay(Employee* e)for (int i=0; iEMPLOYEE_ NUM; i+)ei-pay();int main()PayRoll* payRoll=new PayRo
21、ll;_ employeesEMPLOYEE_ NUM=new Salaried(1001,“Zhang San“,58000.00),/此处省略对其他职工对象的生成new Hourly(1005,“L1“,12,50.00),;payRoll-pay(_);double total=0.0;for(int i=0;iEMPLOYEE_ NUM;i+)(total+=employeesi-getSalary(); /统计周发放工资总额cout“总发放额=“totalendl;delete payRoll; retum 0;(分数:15.00)填空项 1:_ (正确答案::public Empl
22、oyee)解析:填空项 1:_ (正确答案:payRate/52)解析:填空项 1:_ (正确答案::public Employee)解析:填空项 1:_ (正确答案:hours* PayRate)解析:填空项 1:_ (正确答案:Employee*或 static Employee*)解析:填空项 1:_ (正确答案:employees)解析:本题考查考生利用 C+语言设计程序的能力,涉及类、函数和虚函数的定义和相关操作,以及继承关系。考生需要根据给出的案例和执行过程说明,认真阅读理清程序思路,然后完成程序的设计。根据题目中有关信息的描述,Salaried 和 Hourly 是 Employ
23、ee 的子类,它们之间是继承关系。第一空和第三空处需要体现出类之间的继承关系。在子类的构造函数中,调用父类的构造函数,所以继承的权限为public,其语法为:public 父类名。因此,第一空处和第三空处均应填入::public Employee。根据题目的描述及程序段的注释,第二空处实现计算正式员工的周发放工资数。正式员工的周发放工资数为年薪除以总周数,因此应填入 payRate/52。第四空处实现计算计时工的周发放工资数。计时工的周发放工资数为周工作小时数乘上小时工资数。因此,第四空处应填入 hours* PayRate。第五空处用于生成 5 个员工的信息,此处缺少一个类型修饰符。由对象的
24、生成信息可知,此处应填入Employee*或 static Employee*。第六空处调用工资系统类 PayRoll 中的 pay 函数。由类 PayRoll 中构造函数 void pay(Employee* e)的形式可以确定,第六空处应填入 employees。二、试题二(总题数:1,分数:15.00)阅读以下说明和 C+代码,填充代码中的空缺。说明下面的程序用来计算并寻找平面坐标系中给定点中最近的点对(若存在多对,则输出其中的一对即可)。程序运行时,先输入点的个数和一组互异的点的坐标,通过计算每对点之间的距离,从而确定出距离最近的点对。例如,在图所示的 8 个点中,点(1,1)与(2,
25、0.5)是间距最近的点对。(分数:15.00)填空项 1:_ (正确答案:Gpoint*)解析:填空项 1:_ (正确答案:ComputeDistance*)解析:填空项 1:_ (正确答案:numberOtPoints)解析:填空项 1:_ (正确答案:distance(pointsi,pointsj))解析:填空项 1:_ (正确答案:shortestDistancetmpDistance)解析:本题考查考生使用 C+语言进行面向对象程序设计的能力。首先要理解清楚题目中有关最近点对的概念和计算方法,然后阅读程序以实现该功能。第一空处显示创建保存点坐标的数组。这里的 new 运算符用于开辟数
26、组空间,其语法规则为:new 类型 初值。第一空处需要填入一类型修饰符,因此应填入 GPoint*。类似的思路,第二空处应填入ComputeDistance*。根据程序段中的注释,第三空和第四空处实现计算每一对点之间的距离。第三空处为循环控制变量,因为要计算所有对点间的距离,因此应填入 numberOtPoints。第四空处应调用 computeDistance 类的distance 函数计算每一对点 pointsi和 pointsj之间的距离,因此应填入 distance(pointsi,pointsj)。第五空处应填入一个判断条件,以输出距离最小的点对。这可通过比较 shortestDis
27、tance 和tmpDistance 来实现。因此,第五空处应填入 shortestDistancetmpDistance。三、试题三(总题数:1,分数:15.00)阅读下列说明和 C+代码,填充代码中的空缺。说明某学校在学生毕业时要求对其成绩进行综合评定,学生的综合成绩(GPA)由其课程加权平均成绩(Wg)与附加分(Ag)构成,即 GPA=Wg+Ag。设一个学生共修了 n 门课程,则其加权平均成绩(Wg)定义如下:其中,gradei、Ci 分别表示该学生笫 i 门课程的百分制成绩及学分。学生可以通过参加社会活动或学科竞赛获得附加分(Ag)。学生参加社会活动所得的活动分(Apoints)是直接
28、给出的,而竞赛分(Awards)则由下式计算(一个学生最多可参加 m 项学科竞赛):(分数:15.00)填空项 1:_ (正确答案:virtual double getGPA()=0)解析:填空项 1:_ (正确答案:Student(stuNo,name,gs))解析:填空项 1:_ (正确答案:computeWg()+Apoints 或 Student:computeWg()+Apoints)解析:填空项 1:_ (正确答案:Student(stuNo,name,gs))解析:填空项 1:_ (正确答案:computeWg()+Awards 或 Student:computeWg()+Awa
29、rds)解析:填空项 1:_ (正确答案:studentsi-getGPA())解析:本题的程序功能是计算学生的综合成绩(GPA)其中 GPA 由其课程加权平均成绩 Wg 与附加分 Ag 构成,即 GPA=Wg+Ag。首先定义了一个 getGPA()函数并为函数赋初始为 0,第一空填 virtual double getGPA()=0,其中 Virtual 是指在 Windows 下 C+的开发环境,double 定义了 GPA 的值都为双精度浮点数。第二空是计算学生的活动的附加分,调用 Student()函数,括号内的变量用已经定义过的变量名替代,即Student(stuNo,name,gs
30、)。在 Student()函数中调用了 getGPA 函数,引用了题目中给的公式 GPA=Wg+Ag,所以第三空应填 computeWg()+Apoints。第四空是计算学生竞赛的附加分的函数,其中又调用了一次Student 函数,所以同第二空一样填 Student(stuNo,name,gs)。第五空同第三空一样,是在 Student 函数中调用了 getGPA 函数,引用了题目中给的公式 GPA=Wg+Ag,所以第五空应填 computeWg()+Awards,与第三空不同的是,这次 Wg 加的是竞赛的附加分。第六空是在主函数的 for 循环里面,由于共有 3 个学生,所以 i 的取值范围
31、为 03,并将 studentsi的值赋值给 GPA,所以第六空应填 studentsi-getGPA()。四、试题四(总题数:1,分数:15.00)阅读以下说明和 C+代码,将应填入_处的语句或语句成分写在对应栏内。说明某数据文件 students.txt 的内容为 100 名学生的学号和成绩,下面的程序将文件中的数据全部读入对象数组,按分数从高到低进行排序后选出排名前 30%的学生。C+代码#include iostream#include fstream#include stringusing namespace std;class Studentprivate:string sNO;
32、/学号int credit;/分数public:Student(string a,int b)sNO=a;credit=b;Student()int getCredit();void out();_:getCredit()return credit;_:out()Cout“SNO:“sNO“,Credit=“creditendl;class SortStudentpublic:void sort(Student *s,int n);SortStudent();void SortStudent:sort(Student *s,int n)for(int i=0;in-1;i+)for(int j
33、=i+1;jn;j+)if(si._sj._Student temp=si;si=sj;sj=temp;int main(int argc,char* argv)const int number=100; /学生总数ifstream students;students.open(“students.txt“);if(!students.is open()throw 0;Student *testStudent=_number;int k=0;string s;while(getline(students,s,/n)/每次读取一个学生的学号和成绩Student student(s.substr(
34、0,s.find(,),atoi(s.substr(s.find(,)+1).c_str();testStudentk+=student;Students.closeo;_;ss.sort(testStudent,k);cout“top 30%:“+endl;for(k=0;knumber*0.3;k+)testStudentk.out();deletetestStudent;return 0;(分数:15.00)填空项 1:_ (正确答案:int Student)解析:填空项 1:_ (正确答案:void Student)解析:填空项 1:_ (正确答案:getCredit())解析:填空项
35、 1:_ (正确答案:getCredit())解析:填空项 1:_ (正确答案:new Student)解析:填空项 1:_ (正确答案:SortStudent ss=new SortStudent)解析:解析 本题考查类和对象的概念。类的成员函数在类外部进行定义,其格式为:返回类型类名:成员函数名(参数表)。同时返回类型应当与声明时的类型一致。因此第一空中应填“int Student”,第二空中应填“void Student”。第三空和第四空两空显然要填写成绩的信息,Student 类中有两个成员可以获得成绩信息。数据成员 credit 和成员函数 getCredit()。而数据成员cred
36、it 是 private 权限的,只能由该类中的函数和友元函数访问。从 SortStudent 类的定义中可以知道Student 是其成员对象,因此可以访问 public 权限的成员函数 getCredit()。因此,第三空和第四空填“getCredit()”。类的对象首次出现时,需要新建,因此第五空中填“new Student”。ss 对象引用了sort 函数,因此它应该是 SortStudent 类的对象,在使用前需要新建,因此,第六空填“SortStudent ss=new SortSmdent”。五、试题五(总题数:1,分数:20.00)阅读以下说明和 C+代码,将应填入_处的字句写在
37、对应栏内。说明现需要统计某企业员工的月平均工资,即该企业本月发给员工的工资总和除以员工数。假设企业本月发给员工的工资总和为 sumSalary,该企业的员工总数为 employeeNumber,下面的程序代码计算该企业员工本月的平均工资,其中需要处理 employNumber 为 0 的情况。C+代码#include iostreamusing namespace std;class Departmentprotected:float average(float x,int y)if(y=0)throw _;return x/y;public:void caculate(void)float
38、sumSalary;int employeeNumber;trycout“请输入当月工资总和与员工数:“endl;cinsumSalaryemployeeNumber;float k=average(sumSalary,employeeNumber);cout“平均工资:“kendl;_(int e)if(e=0)cout“请重新输入当月工资总和与员工数:“endl;cinsumSalaryemployeeNumber;float k=average(sumSalary,employeeNumber);cout“平均工资:“kendl;void main()try _;d.caculate()
39、;_(int e)if(e=0)cout“程序未正确计算平均工资!“endl;程序运行时,若输入的员工工资总和为 6000,员工数为 5,则屏幕输出为:请输入当月工资总和与员工数:6000 5_若程序运行时,第一次输入的员工工资总和为 6000,员工数为 0,第二次输入的员工工资总和为 0,员工数为 0,则屏幕输出为:请输入当月工资总和与员工数:6000 0_0 0_(分数:20.00)填空项 1:_ (正确答案:0 或 y)解析:填空项 1:_ (正确答案:catch)解析:填空项 1:_ (正确答案:Department d)解析:填空项 1:_ (正确答案:catch)解析:填空项 1:
40、_ (正确答案:平均工资:1200.00)解析:解析 一般而言,try 语句块中编写正常工作的语句,catch 语句块中主要编写用于处理异常情况发生时的语句,而 finally 块中则包含不论是否发生异常都需要执行的语句。若输入的数据为 6000 和 5,则整个程序能够计算出其平均值为 1200,并且输出 caculate 中的输出语句,结果为“平均工资:1200.0”。若输入的数据为 6000 和 0,则程序中 caculate 方法中的 catch 语句会首先捕获到 average 抛出的异常,要求重新输入数据,并再次调用 average 方法,由于输入的数据为 0 和0,所以 avera
41、ge 会再次抛出异常,这个异常将由 main 方法中的 catch 捕获。六、试题六(总题数:1,分数:20.00)阅读以下说明和 C+代码,将应填入_处的字句写在对应栏内。说明已知类 LinkedList 表示列表类,该类具有 4 个方法:addElement()、lastElement()、numberOfElement()以及 removeLastElement()。4 个方法的含义分别如下。 void addElement(Obect):在列表尾部添加一个对象。 Object lastElement():返回列表尾部对象。 int numberOfElement():返回列表中对象的个
42、数。 void removeLastElement():删除列表尾部的对象。现需要借助 LinkedList 来实现一个 Stack 栈类,C+代码 1 和 C+代码 2 分别采用继承和组合的方式来实现。C+代码 1Class Stack:public LinkedListpublic:void push(Object o)(addElement(o); /压栈Object peek()return _; /获取栈顶元素bool isEmpty() /判断栈是否为空return numberOfElement()=0;Object pop /弹栈Object o=lastElement();_
43、;Return 0;C+代码 2class stackprivate:_;public:void push(Object o) /压栈list.addElement(o);object peek /获取栈顶元素return list _;bool isEmpty() /判断栈是否为空retum list.numberOfElement()=0;Object pop() /弹栈Objecto=list.lastElement();list.removeLastElement();return o;问题若类 LinkedList 新增加了一个公有的方法 removeElement(int index),用于删除列表中第 index个元素,则在用继承和组合两种实现栈类 Stack 的方式中,哪种方式下 Stack 对象可访问方法removeElement(int index)?_(A继承 B组合)(分数:20.00)填空项 1:_ (正确答案:lastElement())解析:填空项 1:_ (正确答案:removeLastElement())解析:填空项 1:_ (正确答案:LinkedList list)解析:填空项 1:_