C++期末考试题超详解.docx
《C++期末考试题超详解.docx》由会员分享,可在线阅读,更多相关《C++期末考试题超详解.docx(27页珍藏版)》请在冰豆网上搜索。
C++期末考试题超详解
C++期末考试题(选择、判断与填空)
一、单项选择
1、在C++中,函数原型不能标识(D)
A、函数的返回类型B、函数参数的个数
C、函数参数类型D、函数的功能
解析:
函数原型的格式是
返回值类型函数名(参数列表);
这里面a返回值类型,b参数个数和c参数类型都可以确定了
函数原型也叫函数声明,还叫引用说明。
其目的是实现先调用函数,后定义函数。
下面举例说明:
#include
voidfun(intn);//这就是函数原型。
intmain()
{
intn;
scanf("%d",&n);
fun(n);//有了函数原型,这儿就可以调用了。
即使fun的定义在后面。
return0;
}
voidfun(intn)
{
if(n/2)fun(n/2);
printf("%d",n%2);
}
2、在C++程序中,对象之间的相互通信通过(B)
A、继承实现B、调用成员函数实现
C、封装实现D、函数重载实现
3、对于任意一个类,析构函数的个数最多为(B)
A、0B、1C、2D、3
解析:
析构函数(destructor)与构造函数相反,当对象脱离其作用域时(例如对象所在的函数已调用完毕),系统自动执行析构函数。
析构函数往往用来做“清理善后”的工作(例如在建立对象时用new开辟了一片内存空间,应在退出前在析构函数中用delete释放)。
以C++语言为例,析构函数名也应与类名相同,只是在函数名前面加一个波浪符~,例如~stud(),以区别于构造函数。
它不能带任何参数,也没有返回值(包括void类型)。
只能有一个析构函数,不能重载。
如果用户没有编写析构函数,编译系统会自动生成一个缺省的析构函数,它也不进行任何操作。
所以许多简单的类中没有用显式的析构函数。
4、下面函数模板定义中不正确的是(A)
A、templateB、template
QF(Qx){QF(Qx){
returnQ+x;returnx+x;
}}
C、templateD、template
TF(Tx){TF(Tx){
returnx*x;returnx>1;
}}
5、友元关系不能(A)
A、继承B、是类与类的关系
C、是一个类的成员函数与另一个类的关系D、提高程序的运行效率
解析:
在说明什么是友元之前,我们先说明一下为什么需要友元与友元的缺点:
通常对于普通函数来说,要访问类的保护成员是不可能的,如果想这么做那么必须把类的成员都成为public(共用的),然而这做带来的问题遍是任何外部函数都可以毫无约束的访问它操作它,c++利用friend修饰符,可以让一些你设定的函数能够对这些保护数据进行操作,避免把类成员全部设置成public,最大限度的保护数据成员的安全。
友元能够使得普通函数直接访问类的保护数据,避免了类成员函数的频繁调用,可以节约处理器开销,提高程序的效率,但矛盾的是,即使是最大限度的保护,同样也破坏了类的封装特性,这即是友元的缺点,在现在cpu速度越来越快的今天我们并不推荐使用它,但它作为c++一个必要的知识点,一个完整的组成部分,我们还是需要讨论一下的。
在类里声明一个普通函数,在前面加上friend修饰,那么这个函数就成了该类的友元,可以访问该类的一切成员。
下面我们来看一段代码,看看我们是如何利用友元来访问类的一切成员的。
#include
using namespace std;
class Internet
{
public:
Internet(char *name,char *address)
{
strcpy(Internet:
:
name,name);
strcpy(Internet:
:
address,address);
}
friend void ShowN(Internet &obj);//友元函数的声明
public:
char name[20];
char address[20];
};
void ShowN(Internet &obj)//函数定义,不能写成,void Internet:
:
ShowN(Internet &obj)
{
cout<}
void main()
{
Internet a("中国软件开发实验室","dev-");
ShowN(a);
cin.get();
}
上面的代码通过友元函数的定义,我们成功的访问到了a对象的保护成员name,友元函数并不能看做是类的成员函数,它只是个被声明为类友元的普通函数,所以在类外部函数的定义部分不能够写成voidInternet:
:
ShowN(Internet&obj),这一点要注意。
一个普通函数可以是多个类的友元函数,对上面的代码我们进行修改,注意观察变化:
#include
using namespace std;
class Country;
class Internet
{
public:
Internet(char *name,char *address)
{
strcpy(Internet:
:
name,name);
strcpy(Internet:
:
address,address);
}
friend void ShowN(Internet &obj,Country &cn);//注意这里
public:
char name[20];
char address[20];
};
class Country
{
public:
Country()
{
strcpy(cname,"中国");
}
friend void ShowN(Internet &obj,Country &cn);//注意这里
protected:
char cname[30];
};
void ShowN(Internet &obj,Country &cn)
{
cout<}
void main()
{
Internet a("中国软件开发实验室","dev-");
Country b;
ShowN(a,b);
cin.get();
}
一个类的成员函数函数也可以是另一个类的友元,从而可以使得一个类的成员函数可以操作另一个类的数据成员,我们在下面的代码中增加一类Country,注意观察:
#include
using namespace std;
class Internet;
class Country
{
public:
Country()
{
strcpy(cname,"中国");
}
void Editurl(Internet &temp);//成员函数的声明
protected:
char cname[30];
};
class Internet
{
public:
Internet(char *name,char *address)
{
strcpy(Internet:
:
name,name);
strcpy(Internet:
:
address,address);
}
friend void Country:
:
Editurl(Internet &temp);//友元函数的声明
protected:
char name[20];
char address[20];
};
void Country:
:
Editurl(Internet &temp)//成员函数的外部定义
{
strcpy(temp.address,"dev-");
cout<}
void main()
{
Internet a("中国软件开发实验室","dev-");
Country b;
b.Editurl(a);
cin.get();
}
整个类也可以是另一个类的友元,该友元也可以称做为友类。
友类的每个成员函数都可以访问另一个类的所有成员。
示例代码如下:
#include
using namespace std;
class Internet;
class Country
{
public:
Country()
{
strcpy(cname,"中国");
}
friend class Internet;//友类的声明
protected:
char cname[30];
};
class Internet
{
public:
Internet(char *name,char *address)
{
strcpy(Internet:
:
name,name);
strcpy(Internet:
:
address,address);
}
void Editcname(Country &temp);
protected:
char name[20];
char address[20];
};
void Internet:
:
Editcname(Country &temp)
{
strcpy(ame,"中华人民共和国");
}
void main()
{
Internet a("中国软件开发实验室","dev-");
Country b;
a.Editcname(b);
cin.get();
}
在上面的代码中我们成功的通过Internet类Editcname成员函数操作了Country类的保护成员cname。
在编程中,我们使用友元的另外一个重要原因是为了方便重载操作符的使用,这些内容我们将在后面的教程着重讨论!
6、下面说法正确的是(B)
A、内联函数在运行时是将该函数的目标代码插入每个调用该函数的地方
B、内联函数在编译时是将该函数的目标代码插入每个调用该函数的地方
C、类的内联函数必须在类体内定义
D、类的内联函数必须在类体外通过加关键字inline定义
解析:
内联函数必须是和函数体申明在一起,才有效。
像这样的申明InlineTablefunction(intI)是没有效果的,编译器只是把函数作为普通的函数申明,我们必须定义函数体。
Inlinetablefunction(intI){returnI*I};
这样我们才算定义了一个内联函数。
我们可以把它作为一般的函数一样调用。
但是执行速度确比一般函数的执行速度要快。
我们也可以将定义在类的外部的函数定义为内联函数,比如:
ClassTableClass{
Private:
IntI,j;
Public:
Intadd(){returnI+j;};
Inlineintdec(){returnI-j;}
IntGetNum();
}
inlineinttableclass:
:
GetNum(){
returnI;
}
上面申明的三个函数都是内联函数。
在C++中,在类的内部定义了函数体的函数,被默认为是内联函数。
而不管你是否有inline关键字。
内联函数在C++类中,应用最广的,应该是用来定义存取函数。
我们定义的类中一般会把数据成员定义成私有的或者保护的,这样,外界就不能直接读写我们类成员的数据了。
对于私有或者保护成员的读写就必须使用成员接口函数来进行。
如果我们把这些读写成员函数定义成内联函数的话,将会获得比较好的效率。
Classsample{
Private:
IntnTest;
Public:
Intreadtest(){returnnTest;}
Voidsettest(intI){nTest=I;}
}
当然,内联函数也有一定的局限性。
就是函数中的执行代码不能太多了,如果,内联函数的函数体过大,一般的编译器会放弃内联方式,而采用普通的方式调用函数。
这样,内联函数就和普通函数执行效率一样了。
7、可以用p.a的形式访问派生类对象p的基类成员a,其中a是(D)
A、私有继承的公有成员B、公有继承的私有成员
C、公有继承的保护成员D、公有继承的公有成员
8、在公有派生情况下,有关派生类对象和基类对象的关系,不正确的叙述是(C)
A、派生类的对象可以赋给基类的对象
B、派生类的对象可以初始化基类的引用
C、派生类的对象可以直接访问基类中的成员
D、派生类的对象的地址可以赋给指向基类的指针
•解析:
1.什么是继承和派生
这个概念应该不难理解。
比如父亲是白人,那么儿子也应该也是白人。
那么儿子就成父亲哪继承了肤色的遗传信息。
确切的讲,儿子先从父亲哪继承了全部人类的基本属性,又从自己父亲那里继承特有的白种人信息。
等于是两层继承。
这里的人类,是父亲和儿子公用属性和动作的集合,是父亲和儿子的抽象,所以他叫做基类,又叫父类。
而父亲是人类的一个子类,他除了具备了人类的所有特性外还派生了自己肤色较白,蓝色眼睛等和其他人不一样的地方。
而对于儿子而言,他不但具备了父亲的基本特征,还衍生出了自己的特性,例如头发是黑色卷曲。
他是从父亲哪继承来的,有衍生了自己的特性,所以他叫做父亲的子类,又叫做派生类。
人类:
五官、四肢、肤色、身高。
能吃饭、睡觉、走路。
父亲:
继承了人类的所有特性,派生了白种人的特性
儿子:
继承了父亲的特性,又派生了黑头发等自己的特性
9、对于类定义
classA{
public:
virtualvoidfunc1(){}
voidfunc2(){}
};
classB:
publicA{
public:
voidfunc1(){cout<<″classBfunc1″<virtualvoidfunc2(){cout<<″classBfunc2″<};
下面正确的叙述是(C)
A、A:
:
func2()和B:
:
func1()都是虚函数
B、A:
:
func2()和B:
:
func1()都不是虚函数
C、B:
:
func1()是虚函数,而A:
:
func2()不是虚函数
D、B:
:
func1()不是虚函数,而A:
:
func2()是虚函数
10、继承的情况下,基类成员在派生类中的访问权限(A)
A、受限制B、保持不变C、受保护D、不受保护
11、通过(A)调用虚函数时,采用动态束定。
A、对象指针B、对象名C、成员名限定D、派生类名
12、.在inta=3,*p=&a;中,*p的值是(D)
A、变量a的地址值B、无意义C、变量p的地址值D、3
13、C++类体系中,不能被派生类继承的有(B)
A、转换函数B、构造函数C、虚函数D、静态成员函数
14、假定一个类的构造函数为A(intaa,intbb){a=aa--;b=a*bb--;},则执行Ax(4,5);语句后,x.a和x.b的值分别为(C)
A、4和5B、5和4C、4和20D、20和5
15、C++对C语言作了很多改进,即从面向过程变成为面向对象的主要原因是(D)
A、增加了一些新的运算符B、允许函数重载,并允许设置缺省参数
C、规定函数说明符必须用原型D、引进了类和对象的概念
16、下列符号不能组成标识符的是(A)
A、连接符B、下划线C、大小写字母D、数字字符
17、复制构造函数的形参是(C)。
A、某个对象名B、某个对象的成员名
C、某个对象的引用名D、某个对象的指针名
18、一个函数功能不太复杂,但要求被频繁调用,选用(A)
A、内联函数B、重载函数C、递归函数D、嵌套函数
19、下列不是描述类的成员函数的是(C)
A、构造函数B、析构函数C、友元函数D、拷贝构造函数
20、C++语言中所有在函数中定义的变量,连同形式参数,都属于(B)
A、全局变量B、局部变量C、静态变量D、函数
21、定义新类是通过(C)实现的。
A、信息隐藏B、数据封装C、继承机制D、数据抽象
22、下面有关类说法不正确的是(C)
A、一个类可以有多个构造函数B、一个类只有一个析构函数
C、析构函数需要指定参数D、在一个类中可以说明具有类类型的数据成员
23、派生类的对象只能对它的(A)是可访问的。
A、公有继承的公有成员B、公有继承的私有成员
C、公有继承的保护成员D、私有继承的保护成员
24、下列不能作为类的成员的是(B)
A、自身类对象的指针B、自身类对象
C、自身类对象的引用D、另一个类的对象
25、如果一个类至少有一个纯虚函数,那么就称该类为(A)
A抽象类B虚基类C派生类D以上都不对
26、在派生类中重新定义虚函数时必须在(A)方面与基类保持一致。
A、参数类型B、参数名字C、操作内容D、赋值
27、下列静态数据成员的特性中,(C)是错误的。
A、说明静态数据成员时前边要加修饰符static;
B、静态数据成员要在类体外进行初始化;
C、静态数据成员不是所有对象所共用的;
D、引用静态数据成员时,要在其名称前加<类名>和作用域运算符;
28、关于new运算符的下列描述中,(D)是错误的。
A、它可以用来动态创建对象和对象数组;
B、使用它创建的对象或对象数组可以使用运算符delete删除;
C、使用它创建对象时要调用构造函数;
D、使用它创建对象数组时必须指定初始值;
29、(D)是析构函数的特征。
A、析构函数可以有一个或多个参数;B、析构函数名与类名不同;
C、析构函数的定义只能在类体内; D、一个类中只能定义一个析构函数;
30、假定AB为一个类,则执行ABx;语句时将自动调用该类的(B)
A、有参构造函数B、无参构造函数C、拷贝构造函数D、赋值重载函数
31、C++语言建立类族是通过(B)
A、类的嵌套B、类的继承C、虚函数D、抽象类
32、静态成员函数不能说明为( C )
A、整型函数B、浮点函数C、虚函数D、字符型函数
33、在C++中,数据封装要解决的问题是( D )
A、数据规范化排列B、数据高速转换C、避免数据丢失
D、切断了不同模块之间的数据的非法使用
34、在C++中有下列4条语句:
inthot=100;
int&rsd=hot;
hot=hot+100;
cout<执行这4条语句后输出为( C )
A、0B、100C、200D、300
35、如果class类中的所有成员在定义时都没有使用关键字public、private或protected,则所有成员缺省定义为( C)
A、publicB、protectedC、privateD、static
36、设置虚基类的目的是(A)
A、消除两义性B、简化程序C、提高运行效率D、减少目标代码
37、实现运行时的多态性用(D)
A、重载函数B、构造函数C、析构函数D、虚函数
38、下列特性中,C与C++共有的是(D)
A、继承B、封装C、多态性D、函数定义不能嵌套
39、通常情况下,函数模板中的类型参数个数不能是(A)
A、0B、2C、4D、3
40、在下列成对的表达式中,运算符“+”的意义不相同的一对是(C)
A、5.0+2.0和5.0+2B、5.0+2.0和5+2.0
C、5.0+2.0和5+2D、5+2.0和5.0+2
41、类的指针成员的初始化是通过函数完成的,这个函数通常是(B)
A、析构函数B、构造函数C、其它成员函数D、友元函数
42、要禁止修改指针p本身,又要禁止修改p所指向的数据,这样的指针应定义为(D)
A、constchar*p=“ABCD”;B、charconst*p=“ABCD”;
C、char*constp=“ABCD”;D、constchar*constp=“ABCD”;
43、静态成员函数没有(