(A)2 (B) 5 (C) 4 (D)79.友元的作用之一是 。
(A)提高程序的执行效率 (B)加强类的封装性
(C)增加成员函数的种类 (D)实现数据的隐藏性
10.使用派生类的主要原因是 。
(A)提高程序的运行效率 (B)提高代码的可重用性
(C)加强类的封装性 (D)实现数据的隐藏
二、填空题(本大题共10小题,每小题2分,共20分)//内容大多来自书中的习题和模拟考试题
1.引用通常用作函数的 和返回值。
2.构造函数名同类名,构造函数无函数返回类型。类中可以有 个构造函数,它们由不同的参数表区分。如果类说明中没有给出构造函数,则C++编译器会自动给出一个默认的构造函数。
3.一个类只有一个析构函数, 时,系统会自动调用析构函数。
4.在C++中“流”是表示数据从一个对象到另一个对象的传送。从流中取得数据称为提取操作,用符号 表示;向流中添加数据称为插入操作,用符号 表示。
5.运算符重载时,其函数名由关键字operator和该运算符构成。成员函数重载双目运算符时,左操作数是 ,右操作数是 。
6.C++根据文件内容的数据格式可分为两类:文本文件和 ,前者存取的最小信息单位为字符,后者为字节。
7.使用变量名访问变量,是按变量的地址来直接存取变量称为 访问方式;使用指针变量取得另一变量的地址再访问变量称为间接访问方式。
8.C++中多态性包括两种多态性:编译时的和运行时的。前者是通过函数和运算符的重载实现的,而后者是通过类继承关系和 来实现的。
9.C++中多态性包括两种多态性:编译时的和运行时的。前者是通过函数和运算符的重载实现的,而后者是通过类继承关系和 虚函数 来实现的。
10.被定义为形参的是在函数中起 自变量 作用的变量,形参只能用 变量名 表示。实参的作用是 将实际参数的值传递给形参 ,实参可以用具有值的变量 、 常量 、 表达式 表示。
11.局部域包括块域 、函数域和函数原型域 。使用局部变量的意义在于局部变量具有局部作用域使得程序在不同块中可以使用同名变量 。
12.静态局部变量存储在全局数据 区,在编译 时候建立,生存期为全局生存期 ,如定义时未显式初始化,则其初值为 0 。
13.局部变量存储在栈 区,在函数或块开始执行时 时候建立,生存期为函数或块的执行期,如定义时未显式初始化,则其初值为随机值 。
14.编译预处理的作用是将源程序文件进行处理,生成一个中间文件,编译系统对此中间文件进行编译并生成目标代码 ,预处理指令的标志是# 。多文件系统中,程序由 工程文件 来管理,用户自定义头文件中通常定义一些用户构造的数据类型(如枚举类型),外部变量,外部函数、常量和内联函数等具有一定通用性或常用的量 。
15.通常在逻辑上,同一类的每个对象都有 的 代码区,用以存储成员函数。而在物理上通常只有 共用的 代码区。只有在 在类说明中 定义,并 不包括循环等复杂结构 的函数和加了关键字 inline 的函数例外。
16.C++中支持三种域: 局部域(local scope) 、 名字空间域(namespace scope) 、 类域(class scope) 。函数域被包括在 局部域 中,全局域被包括在 名字空间域 中。using指示符以关键字using开头,后面是关键字 namespace ,最后是 名字空间名 。这样表示以后在该名字空间中所有成员都 可以直接被使用 。如不使用using指示符则在使用时要加::,称为域 运算符。
17.构造函数的任务是 初始化数据成员 。构造函数无 函数返回类型说明 。类中可以有 1个或 多 个构造函数,它们由 不同的参数表 区分。如果类说明中没有给出构造函数,则C++编译器会 自动给出一个默认的构造函数 。拷贝构造函数的参数是 同一类对象的引用 ,当程序没有给出复制构造函数时,系统会自动提供 默认的的复制构造函,称为默认的按成员语义支持 支持,这样的复制构造函数中每个类成员 被依次复制 。
18.纯虚函数定义时在函数参数表后加 (1) ,它表明程序员对函数 (2) ,其本质是将指向函数体的指针定为 (3) 。
答案:(1)=0(2)不定义(3)NULL
19.运算符重载时,其函数名由 关键字operator和该运算符 构成。成员函数重载双目运算符时,左操作数是 对象 ,右操作数是 该函数的参数 。
20.面向过程的程序设计中程序模型描述为 “程序=算法+数据结构”。其数据与数据处理是分离的 ,面向对象程序设计的程序模型可描述为 程序=(对象+对象+……+对象)+消息;对象=(算法+数据结构)。面向对象设计将数据和对数据的操作方法放在一起,形成一个相对的整体——对象(Object),并通过简单的接口与外部联系。对象之间通过消息(Message)进行通讯 。
21.固定指向一个对象的指针,称为 (1) ,即 (2) ,定义时const放在 (3) 。而指向“常量”的指针称为 (4) ,指针本身可以指向别的对象,但 (5) ,定义时const放在 (6) 。
答案:(1)指针常量(2)指针本身是常量(3)const放在类型说明之后,变量名之前(4)常量指针(5)不能通过该指针修改对象(6)const放在类型说明之前
22.数组名在表达式中被自动转换为指向 (1) 的指针常量,数组名是地址,但数组名中放的地址是 (2) ,所以数组名 (3) 。这样数组名可以由 (4) 来代替,C++这样做使用时十分方便,但丢失了数组的另一要素 (5) ,数组名是指向数组 (6) 的指针,而不是指向数组 (7)的。编译器按数组定义的大小分配内存,但运行时对 (8) 不加检测,这会带来无法预知的严重错误。
答案:(1)数组第一个元素(2)不可改变的(3)称指针常量(4)指针(5)数组元素的数量(6)元素(7)整体(8)对数组的边界不加检测
23.模板是为了实现代码的 (1) ,它把数据类型改为一个 (2) ,称为 (3) 程序设计。模板包括 (4) 和 (5) 。
答案:(1)重用(2)设计参数(3)参数化(parameterize)(4)函数模板(function template)(5)类模板(class template)
24.调用函数模板时,可以显式指定模板参数类型,也可以隐式进行,称为 (1) ,这是根据 (2) 来决定的。
答案:(1)模板实参推演(template argument deduction)(2)一组实际类型或(和)值
25.C/C++定义了4个内存区间: (1) 、 (2) 、 (3) 和 (4) 。
答案:(1)代码区,存放程序代码; (2)全局变量与静态变量区,存放全局变量或对象(包括静态);(3)局部变量区即栈(stack)区,存放局部变量;(4)自由存储区(free store),即动态存储区或堆(heap)区。
26.静态定义的变量和对象用标识符命名,称为 (1) ;而动态建立的称为 (2) ,动态建立对象的初始化是通过 (3) 实现 (4) 。
答案:(1)命名对象(2)无名对象(3)初始化式(initializer) (4)显式初始化
27.在用new运算符建立一个三维数组15*30*10时,使用了 (1) 个下标运算符,对应的用delete运算符注销这个三维数组时使用了 (2) 个下标运算符。new返回的指针是指向 (3) 的指针。
答案:(1)3个 (2)1个 (3)30行10列的2位数组
28.当动态分配失败,系统采用 (1) 来表示发生了异常。如果new返回的指针丢失,则所分配的自由存储区空间无法收回,称为 (2) 。这部分空间必须在 (3) 才能找回,这是因为无名对象的生命期 (4) 。
答案:(1)返回一个空指针(NULL)(2)内存泄漏(3)重新启动计算机后(4)并不依赖于建立它的作用域
29.如果类α继承了类β,则类α称为 (1) 类,而类β称为 (2) 类。 (3) 类的对象可作为 (4) 类的对象处理,反过来不行,因为 (5) 。如果强制转换则要注意 (6) 。
答案:(1)基类(2)派生类(3)派生类(4)基类(5)派生类有一些新成员(6)只能派生类强制转换为基类
30.当用public继承从基类派生一个类时,基类的public成员成为派生类的 (1) 成员,protected成员成为派生类的 (2) 成员,对private成员是 (3) 。公有派生可以使其类的 (4) ,所以公有派生是主流。
答案:(1)public成员(2)protected成员(3)不可访问(4)接口不变
31.利用继承能够实现 (1) 。这种实现缩短了程序开发的时间,VC++中的 (2) 很好地体现了这一点。
答案:(1)代码的复用(2)MFC编程
32.一个派生类只有一个直接基类的情况称为 (1) ,而有多个直接基类的情况称为(2) 。继承体现了类的 (3) 概念,这在MFC中得到了很好表现,MFC中只采用了 (4) 。
答案:(1)单继承(2)多重继承(3)层次(4)单继承
33.在基类中将一个成员函数说明成虚函数后,在其派生类中只要 (1) 、 (2) 和 (3) 完全一样就认为是虚函数,而不必再加关键字 (4) 。如有任何不同,则认为是 (5) 而不是虚函数。除了非成员函数不能作为虚函数外, (6) 、 (7) 和 (8) 也不能作为虚函数。
答案:(1)同虚函数名(2)同参数表(3)同返回类型。如基类中返回基类指针,而派生类中返回派生类指针是允许的(4)virtual(5)重载(6)静态成员函数(7)内联函数(8)构造函数
三、写出下列各程序运行后的输出结果(本大题共7小题,每小题4分,共28分)
1.#include class base{public:int a1; base(){} base(int n1){a1=1;} };
class A:virtual public base{public:int a2; A(int n1,int n2):base(n1){a2=n2;}};
class B:virtual public base{public:int a3; B(int n2,int n3):base(100){a3=n3;} };
class C:public A,public B
{ public:int a4;C(int n1,int n2,int n3,int n4):A(n1,n2),B(n1,n3),base(8){a4=n4; } };
void main(){ C x(1,2,3,4),*pc=&x;cout<a4;B *pb=&x;cout<a3;A *pa=&x;cout<a2;base *p=&x;cout<a1;}输出结果为:
2.#include #includeclass szxy{ char *name;int age;szxy *next;
public:szxy(){}
szxy(char *n,int x,szxy *p=NULL)
{name=new char[strlen(n)+1];strcpy(name,n); age=x;next=p;}
~szxy(){delete name;}
void list(szxy *t){for(;t;t=t->next)cout<name<age;} };void main()
{ szxy x2("李",4, NULL);szxy x1("张",3,&x2);x1.list(&x1); }
输出结果为:
3.#include class base0{public:virtual void v(){cout<<"大江";} };
class base1:public base0{public:void v(){cout<<"南北";} };
class A1:public base1{public:void v(){cout<<"我";} };
class A2:public A1{public:void v(){cout<<"爱";} };
class B1:public base1{public:void v(){cout<<"你";} };
class B2:public B1{public:void v(){cout<<"们";} };
void main(){base0 *p;
B1 b1;p=&b1;p->v();B2 b2;p=&b2;p->v();
A2 a2;p=&a2;p->v();A1 a1;p=&a1;p->v();}
输出结果为:
4.#include class jk24{ int *p; int size;
public:jk24(int n){ size=n;p=new int[size]; } ~jk24(){ delete p; }
friend ostream&operator<<(ostream&,jk24&); int operator[](int i){ return p[i]; } void operator=(int m){ for(int i=0;iostream&operator<<(ostream&os,jk24&T){ for(int i=0;ivoid main(){ jk24 I(4);I=1;cout<输出结果为:5.#include#includeclass jk25{ char *name;
public:jk25(char *p){name=new char[strlen(p)+1];strcpy(name,p);cout<<1;}
~jk25(){cout<<5;}
void list(){cout<class jk26{ jk25 z;int age;public:jk26(char *p,int a):z(p){age=a;cout<<2;}
~jk26(){cout<<4;}
void disp(){z.list();} };
void main(){ jk26 w("3",3); w.disp(); }}
输出结果为:
6.#includeclass jsjx{ double *data; int length;
public:jsjx(){}
jsjx(double *p,int n){data=p;length=n;}
jsjx(jsjx&x){data=x.data;length=x.length;}
jsjx&operator=(jsjx&x){data=x.data;length=x.length;return *this;}
double sum(jsjx x){ double s=0;while(x.length>0){s=s+*x.data;x.data++;x.length--;}
return s;} };
void main(){ double a[10]={0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0 };
jsjx z(a,10),z2=z; cout<输出结果为:7.#include class stack{ int size,*root, *top;
public: stack(int n){size=n;top=root=new int[size];} ~stack(){delete root;}
void push(int data){if(top>=root+size)cout<<"no";else {*top++=data;cout<void pop(){if(top<=root)cout<<"no";else {top--;cout<<*top+22<<*top-27;} } };void main(){ stack *p=new stack(10);p->push(12); p->push(34);
p->pop(); delete p; }
输出结果为:
8.#includeclass wg{ double m;static double sm;static int sn;
public:wg(double m0){m=m0;sm=sm+m0;sn++;}
~wg(){sm=sm-m;sn--;}
static void disp(){ cout<double wg::sm=0;int wg::sn=0;void main(){
wg x1(5.1),x2(6.2),x3(32.12),x4(3.5),x5(66.6),x6(1.2),x7(3.4),x8(8.8),x9(27.8);
x3.~wg();x5.~wg();
wg::disp(); }
输出结果为:
四、编程题(本大题共4小题,每小题8分,共32分)
1.#include//注意: 输出<<、输入>>运算符只能重载为友员函数class jk{
public: int size;char *p;
jk(int s){ size=s;p="yes";}
//在下面写出输出运算符<<重载函数的声明语句
friend ostream& operator<<(ostream&,jk&);
};
//在下面编写出输出运算符<<重载函数的内容
ostream&operator<<(ostream&os,jk &x){ os<cout<<"自己编写的输出运算符<<重载函数!\\n"; return os; }void main()
{
jk x(20);
cout<}2.#include//+号运算符重载函数可以有成员函数和友元函数两种形式class complex{
double real,imag;
public: complex(double a=0.0,double b=0.0){ real=a;imag=b;}
void disp(){cout<<'('< //在下面编写出+号运算符重载友元函数的内容complex operator+(complex &c){
double x=this->real+c.real;
double y=this->imag+c.imag;
return complex(x,y); }
};
void main()
{
complex z1(1,1),z2(2,2),z3;
z3=z1+z2;
z3.disp();
}
3.创建一个名为time的类,它包括分别表示小时、分钟和秒的int类型的数据成员以及两个构造函数,一个构造函数将数据成员初始化为0,另一个将数据成员初始化为一个固定的值。另有一成员函数将时间以10:10:10的格式显示在屏幕上,编写成为一个完整的程序。
class time{
int x,y,z;
public: time(){x=y=z=0;}
time(int a,int b,int c){x=a;y=b;z=c;}
void disp(){cout<};4.设计一个学校在册人员类(Person)。数据成员包括:身份证号(IdPerson),姓名(Name),性别(Sex),生日(Birthday)和家庭住址(HomeAddress)。成员函数包括构造函数与拷贝构造函数。还包括人员信息的录入和显示。编写成为一个完整的程序。
#include#includeclass person{
char Idperson[20]; //身份证号
char Name[20]; //姓名
char Sex; //性别
int Birthday; //生日,格式1986年8月18日写作19860818
char HomeAddress[50]; //家庭地址
public:
person(char *,char *,char,int,char*);
person(person &);
person(){}
void inputperson();
void printperson(); };
person::person(char *id,char *name,char s,int birthday,char *homeadd)
{ strcpy(Idperson,id); strcpy(Name,name); Sex=sex;
Birthday=birthday; strcpy(HomeAddress,homeadd); }
person::person(person &s)
{ strcpy(Idperson,s.Idperson); strcpy(Name,s.Name);
Sex=s.Sex; Birthday=s.Birthday;strcpy(HomeAddress,s.HomeAddress); }
void person::inputperson()
{
cout<<"请输入身份证号,18位数字:"< cout<<"请输入姓名:"< cout<<"请输入性别m或w:"<>Sex; cout<<"请输入生日,格式1986年8月18日写作19860818:"<>Birthday; cin.get(); //吸收回车符,否则地址输不进去
cout<<"请输入地址:"<}void person::printperson(){
cout<void main(){ person x(“342222************”,”kkk”,’m’,19701011,”1234567”);
person y=x;
person z;z.inputperson();z.printperson(); }
5.建立一个基类CBuilding,用来存储一座楼房的层数、房间数以及它的总平方英尺数。建立派生类Chousing,继承CBuilding,并存储下面的内容:卧室和浴室的数量。另外再建立派生类COfficing,继承CBuilding,并存储灭火器和电话的数目。然后编写应用程序,建立住宅对象和办公楼对象,并输出它们的有关数据,编写成为一个完整的程序。
#include#includeclass CBuilding{int x1,x2,x3;
public:CBuilding(int t1,int t2,int t3){x1=t1;x2=t2;x3=t3;}
void disp1(){cout<class Chousing:public CBuilding{int y1,y2;public:Chousing(int t1,int t2,int t3,int t4,int t5):CBuilding(t1,t2,t3)
{y1=t4;y2=t5;}
void disp2(){cout<class COfficing:public CBuilding{int z1,z2;public:COfficing(int t1,int t2,int t3,int t4,int t5):CBuilding(t1,t2,t3)
{z1=t4;z2=t5;}
void disp3(){cout<void main(){ chousing x(5,100,10000,200,100);
x.disp1(); x.disp2();
COfficing y(5,100,10000,130,400);
y.disp1();y.disp3(); }
6.某公司雇员(employee)包括技术人员(technician)和销售员(salesman)。以employ类为虚基类派生出technician和salesman类;employee类的属性包括姓名、职工号、基本工资,业绩工资,月薪(实发基本工资加业绩工资)。操作包括月薪计算函数(pay()),该函数要求输入请假天数,扣去应扣工资后,得出实发基本工资。
technician类派生的属性有每小时附加酬金和当月工作时数,及研究完成进度系数。业绩工资为三者之积。也包括同名的pay()函数,工资总额为基本工资加业绩工资。
salesman类派生的属性有当月销售额和酬金提取百分比,业绩工资为两者之积。也包括同名的pay()函数,工资总额为基本工资加业绩工资。编写所有的类。
class employee{
protected:
char name[20];//姓名
int ID;//职工号
double basesalary;//基本基本
double careersalary;//业绩工资
double salary; //月薪
public:
employee(char *n,int i=0, double bs=0.0, double cs=0.0, double s=0.0)
{strcpy(name,n);ID=i;basesalary=bs;careersalary=cs;salary=s;}
void pay(); }; //月薪计算函数
void employee::pay(){
int days;
cout<<"请输入请假天数:\\n"; cin>>days;
salary=basesalary-basesalary/23*days+careersalary; }
class technician:public employee{
protected:
double hours;//月工作时数
double perhour;//每小时附加酬金
double shfactor;//研究进度系数
public:
technician(char n[20],int i,double bs, double t1=0.0,double t2=0.0,double t3=0.0)
:employee(n,i,bs){ hours=t1;perhour=t2;shfactor=t3;}
void pay(); };
void technician::pay(){
int days;
cout<<"请输入请假天数:\\n"; cin>>days;
cout<<"请输入研究进度系数:\\n"; cin>>shfactor;
hours=8*(23-days);
careersalary=perhour*hours*shfactor*(23-days)/23;
salary=basesalary-basesalary/23*days+careersalary; }
class salesman:public employee{
protected:
double amount;//销售额
double slfactor;//提成比例
public:
salesman(char n[20],int i,double bs, double t1=0.0,double t2=0.0)
:employee(n,i,bs){ amount=t1;slfactor=t2;}
void pay(); };
void salesman::pay(){
int days;
cout<<"请输入请假天数:\\n"; cin>>days;
cout<<"请输入销售额:\\n"; cin>>amount;
careersalary=amount*slfactor;
salary=basesalary-basesalary/23*days+careersalary; }
上机考试说明
题目全是书上讲过的例题,它们是:
P235 10.1
P241 10.2 命令按钮中只有1、2、3、4、5、6、7、8、9、0、+、-、*、/、=十五个按钮。
P244 10.3 课程名称可以取得简单的,由教师临时指定。
P248 10.4 舍去Reset和Exit两个命令按钮。
P256 10.5 舍去退出命令按钮。
P263 11.1 字体菜单中只含有粗体、斜体、下划线和问候四个菜单项。
要求:
1.临时随机抽选其中的1题。
2.所有名称中都要含有本人的学号。
3.有的名称是临时指定的。
4.全班分二批上机考试,距离拉开,不准讲话,不准带U盘,可以带书。
5. 编程题6选4,程序运行题8选7。