1、国家二级(C+)机试-试卷 15-2 及答案解析(总分:86.00,做题时间:90 分钟)一、选择题(总题数:40,分数:80.00)1.运算符重载是对已有的运算符赋予多重含义,因此( )。(分数:2.00)A.可以对基本类型(如 int 类型)的数据,重新定义“+“运算符的含义B.可以改变一个已有运算符的优先级和操作数个数C.只能重载 C+中已经有的运算符,不能定义新运算符D.C+中已经有的所有运算符都可以重载2.有如下程序: #include using namespace std; class Obj static int i; public: Obj() i+; Obj() i-; s
2、tatic int getVal() return i; ; int Obj:i=0; void f() Obj ob2; couta = a; / static int g() return a; / void h(int b) Test:b = b; ; / private:int a;static int b;const int c;int Test:b = 0;在标注号码的行中,能被正确编译的是( )。(分数:2.00)A.B.C.D.34.将 ER 图转换为关系模式时,实体和联系都可以表示为( )。(分数:2.00)A.属性B.键C.关系D.域35.下列有关继承和派生的叙述中,正确的
3、是( )。(分数:2.00)A.派生类不能访问基类的保护成员B.作为虚基类的类不能被实例化C.派生类应当向基类的构造函数传递参数D.虚函数必须在派生类中重新实现36.下列叙述中正确的是( )。(分数:2.00)A.有一个以上根结点的数据结构不一定是非线性结构B.只有一个根结点的数据结构不一定是线性结构C.循环链表是非线性结构D.双向链表是非线性结构37.已知表达式-a 中的“-“是作为成员函数重载的运算符,则与-a 等效的运算符函数调用形式为(分数:2.00)A.a.operator-(1)B.operator-(a)C.operator-(a,1)D.a.operator-()38.下列链表
4、中,其逻辑结构属于非线性结构的是(分数:2.00)A.二叉链表B.循环链表C.双向链表D.带链的栈39.将运算符*重载为类成员函数时,其参数表中有且仅有一个参数,说明该运算符是(分数:2.00)A.无操作数的运算符B.无操作数的运算符C.二元运算符D.三元运算符40.下列函数模板的定义中,合法的是(分数:2.00)A.templateTabs(Tx)returnx“不能重载为类的成员函数,因为如果将这两种操作符重载为类的成员函数,左操作数将只能是该类类型的对象,这样的用法与正常 I/O 使用方式相反,为了支持正常用法,左操作数必须为标准库 I/O 内置类型,这又意味着如果该操作符重载为类的成员
5、,那它必须是标准库内置类型的类成员,而标准库内置的类是不能人为添加成员的,D 选项错误;答案为 C。13.下列有关继承和派生的表述中,正确的是(分数:2.00)A.派生类的成员函数可以访问基类的所有成员B.如果一个派生类私有继承其基类,则该派生类的对象能访问基类的保护成员C.基类对象可以直接赋值给派生类对象D.如果派生类没有实现基类的一个纯虚函数,则该派生类是一个抽象类 解析:解析:派生类对基类成员的访问权限由基类成员的访问标识和类派生列表中的访问标识共同决定的,选项 A 错误;派生类私有继承基类,基类的保护成员在派生类中为 private 成员,派生类对象不可见,选项 B 错误;派生类包含基
6、类中没有的成员变量和成员函数,将基类对象赋给派生类对象,在调用这些成员时报错,选项 C 错误;答案为 D。14.下列关于基类和派生类关系的叙述中,正确的是(分数:2.00)A.派生类中的成员可以访问基类中的任何成员B.每个类最多只能有一个直接基类C.对基类构造函数的调用不能出现在派生类构造函数的初始化列表中D.派生类除了继承基类的成员,还可以定义新的成员 解析:解析:派生类对基类成员的访问权限由基类成员的访问标识和类派生列表中的访问标识共同决定的,选项 A 错误;多重继承的派生类可以有多个直接基类,选项 B 错误;派生类构造函数可以隐式调用基类的默认构造函数初始化对象的基类部分,也可以在派生类
7、构造函数初始化列表中显示调用基类构造函数,选项 C 错误;答案为 D。15.下列符号中,正确的 C+标识符是( )。(分数:2.00)A.enumB.2bC.foo-9D._32 解析:解析:本题考查 C+标识符的命名规则,规定如下:所有标识符可以由字母、数字和下画线组成,且必须以字母或下画线开头;C+的关键字不能作为标识符;大、小写字母表示不同意义,即代表不同的标识符,如 mun 和 Mun。A 选项是 C+的关键字,B 选项不能以数字开头,C 选项“-“不能用于组成标识符。16.ClassA 是一个类,且有如下语句序列 ClassA c1,*c2;ClassA *c3=new MyClas
8、s;ClassA 则ClassA 的构造函数被调用的次数是(分数:2.00)A.1B.2 C.3D.5解析:解析:定义一个 ClassA 类型的对象 c1,生成新对象 c1,调用默认构造函数;定义一个 ClassA 类型的指针 c2,指针未赋初值,没有新对象生成,没有调用构造函数;定义一个 ClassA 类型的指针 c3,使用动态分配方式为 c3 分配内存,生成新的对象,将 c3 初始化为新对象的地址,调用默认构造函数;定义一个 ClassA 类型的引用 c4,引用 c1 对象,没有新对象生成,未调用构造函数;答案为 B。17.下列叙述中正确的是(分数:2.00)A.所谓有序表是指在顺序存储空
9、间内连续存放的元素序列B.有序表只能顺序存储在连续的存储空间内C.有序表可以用链接存储方式存储在不连续的存储空间内 D.任何存储方式的有序表均能采用二分法进行查找解析:解析:有序是特指元素按非递减排列,即从小到大排列,但允许相邻元素相等,A 选项错误。有序表可以顺序存储也可以链式存储,B 选项错。能使用二分法查找的线性表必须满足两个条件:用顺序存储结构;线性表是有序表,D 选项错误。故 C 选项正确。18.有如下程序: #include using namespace std; class A public: static int a; void init() a = 10; A(int a
10、= 5) init(); a+=10; ; int A:a = 0; A obj; int main() cout “必须重载为成员函数,将这些操作符定义为非成员函数将在编译时标记为错误,友元函数是非成员函数,答案为 B。33.有如下类定义:class Test public:Test() a = 0; c = 0; / int f(int a) const this-a = a; / static int g() return a; / void h(int b) Test:b = b; ; / private:int a;static int b;const int c;int Test:
11、b = 0;在标注号码的行中,能被正确编译的是( )。(分数:2.00)A.B.C.D. 解析:解析:只能通过构造函数的参数初始化列表对常数据成员进行初始化,本题中常数据成员为 c。通过默认构造函数初始化 c,所以不正确。常成员函数只能引用本类中数据成员,而不能修改它,所以不正确。静态成员函数由于没有 this 指针,所以不能访问本类中的非静态成员,所以错误。34.将 ER 图转换为关系模式时,实体和联系都可以表示为( )。(分数:2.00)A.属性B.键C.关系 D.域解析:解析:从 ER 图到关系模式的转换是比较直接的,实体与联系都可以表示成关系,ER 图中属性也可以转换成关系的属性。35
12、.下列有关继承和派生的叙述中,正确的是( )。(分数:2.00)A.派生类不能访问基类的保护成员B.作为虚基类的类不能被实例化C.派生类应当向基类的构造函数传递参数 D.虚函数必须在派生类中重新实现解析:解析:派生类可以访问基类的保护成员,而不能访问基类的私有成员。作为虚基类的类可以被实例化。虚函数如果没有派生类中重新实现,那么仍然使用基类的成员函数。36.下列叙述中正确的是( )。(分数:2.00)A.有一个以上根结点的数据结构不一定是非线性结构B.只有一个根结点的数据结构不一定是线性结构 C.循环链表是非线性结构D.双向链表是非线性结构解析:解析:线性结构应满足:有且只有一个根结点与每个结
13、点最多有一个前件,也最多有一个后件,所以 B)正确。所以有一个以上根结点的数据结构一定是非线性结构,所以 A)错误。循环链表和双向链表都是线性结构的数据结构。37.已知表达式-a 中的“-“是作为成员函数重载的运算符,则与-a 等效的运算符函数调用形式为(分数:2.00)A.a.operator-(1)B.operator-(a)C.operator-(a,1)D.a.operator-() 解析:解析:本题考查重载自减运算符-,根据重载的规则,只有 D 选项能够正确调用重载函数。38.下列链表中,其逻辑结构属于非线性结构的是(分数:2.00)A.二叉链表 B.循环链表C.双向链表D.带链的栈
14、解析:解析:在定义的链表中,若只含有一个指针域来存放下一个元素地址,称这样的链表为单链表或线性链表。带链的栈可以用来收集计算机存储空间中所有空闲的存储结点,是线性表。在单链表中的结点中增加一个指针域指向它的直接前件,这样的链表,就称为双向链表(一个结点中含有两个指针),也是线性链表。循环链表具有单链表的特征,但又不需要增加额外的存贮空间,仅对表的链接方式稍做改变,使得对表的处理更加方便灵活,属于线性链表。二叉链表是二叉树的物理实现,是一种存储结构,不属于线性结构。答案为 A 选项。39.将运算符*重载为类成员函数时,其参数表中有且仅有一个参数,说明该运算符是(分数:2.00)A.无操作数的运算
15、符B.无操作数的运算符C.二元运算符 D.三元运算符解析:解析:本题考查运算符重载,题目中将*重载为类成员函数时,如果是一元运算符,其参数就是默认的 this,而如果是二元运算符,其参数表中有且仅有一个参数,所以该运算符是二元运算符。40.下列函数模板的定义中,合法的是(分数:2.00)A.templateTabs(Tx)returnx0?-x:x; B.templateclassTabs(Tx)returnx0?-x:x;C.templateTabs(Tx)returnx0?-x:x;D.templateTabs(Tx)returnx0?-x:x;解析:解析:本题考查模板的定义,一般形式为:
16、templateT 通用函数定义,所以只有 A 选项正确。二、基本操作题(总题数:1,分数:2.00)41.请使用 VC6 或使用【答题】菜单打开考生文件夹 proj1 下的工程 proj1,此工程包含一个源程序文件proj1cpp。文件中将表示数组元素个数的常量 Size 定义为 4,并用 int 类型对类模板进行了实例化。文件中位于每个注释“ERROR*found*”之后的一行语句存在错误。请改正这些错误,使程序的输出结果为:1234 注意:模板参数名用 T。只修改注释“ERROR*found*”的下一行语句,不要改动程序中的其他内容。proj1cpp#includeiostreamusi
17、ngnamespacestd;将数组元素个数 Size 定义为4ERROR*found*constintSize;templatetypenameTclassMyClasspublic:MyClass(T*P)for(inti=0;iSize;i+)arrayi=pi;voidPrint();private:TarraySize;templatetypenameTERROR*found*voidMyClass:Print()for(inti=0;iSize;i+)coutarrayit;intmain()intintArraySize=1,2,3,4;ERROR*found*MyClassdo
18、ubleobj(intArray);objPrint(),coutend1;return0;(分数:2.00)_正确答案:(正确答案:(1)eonstintSize=4; (2)voidMyClass:Print() (3)MyClassobj(intArray);)解析:解析:(1)主要考查考生对 const 变量的掌握,因为 const 变量不能修改,所以在定义的同时必须初始化。 (2)主要考查考生对模板类的成员函数定义的掌握,因为 MyClass 类是模板类,所以在定义该函数时要加上模板标识符“”,即语句 voidMyClass:Print( )。 (3)主要考查考生对模板类构造函数的调
19、用的理解,从上一条语句 intintArraySize=1,2,3,4;中可以知道 intArray 为 int 型,因此定义 obj 时要使用,即 MyClassobj(intAtray);。三、简单应用题(总题数:1,分数:2.00)42.请使用 VC6 或使用【答题】菜单打开考生文件夹 proj2 下的工程 proj2,此工程中含有一个源程序文件 proj2cpp。函数 char*GetNum(char*8re,char*buf)从 src 开始扫描下一个数字字符序列,并将其作为一个字符串取出放入字符串空间 bur 中。函数返回扫描的终止位置,如果返回 NULL 表示没有扫描到数字字符序
20、列。运行程序时,如果输入的一行字符序列是 ABC012XYZ378MN274WS 则输出为:Digitstring1is012Digitstring2is378Digitstring3is274 注意:只在横线处编写适当代码,不要删除或移动“*found*”。proj2cpp#includeiostreamusingnamespacestd;char*GetNum(char*src,char*buf)while(*src!=0)if(isdigit(*src)break;Src+;if(*src=0)*found*_;:while(*src!=!0isdigit(*src)*found*_;b
21、uf+;Src+;*buf=0;returnsrc;intmain()charstri00,digits20;cingetline(str,100);char*P:str;inti=1;while(p=GetNum(p,digits)!=NULL)cout“Digitstring“i“is“digitsend1;*found*_;return0;(分数:2.00)_正确答案:(正确答案:(1)returnNULL (2)*buf=*src (3)i+)解析:解析:(1)主要考查考生对 if 语句的掌握,由判断条件 if(*src=0),说明字符串 src 为空,则返回 NULL 即可。 (2)
22、主要考查考生对 while 循环语句的掌握,while 语句的循环条件为*src!=0&isdigit(*src),该条件是指,若字符串 src 不为空并且*src 指向的字符为数字字符,则进行循环。题目要求把数字字符放入字符串 buf 中,因此为*buf=*src。 (3)主要考查考生对 while 循环语句的掌握,从上一行语句 cout“Digitstring“i“is“digitsend1;中可以得出,题目要求输出的 i 是递增的,因此这里需添加语句 i+。四、综合应用题(总题数:1,分数:2.00)43.请使用 VC6 或使用【答题】菜单打开考生文件夹 proj3 下的工程 proj3
23、,其中声明的 CDeepCopy 是一个用于表示矩阵的类。请编写这个类的赋值运算符成员函数 operator=,以实现深层复制。要求:补充编制的内容写在“*333*”与“*666*”之间。不得修改程序的其他部分。注意:程序最后将结果输出到文件 outdat 中。输出函数 writeToFile 已经编译为 obj文件,并且在本程序中调用。CDeepCopyh#includeiostream#includestringusingnamespacestd;classCDeepCopypublic:intn;动态数组的元素个数 int*p;动态数组首地址 CDeepCopy(int);CDeepCo
24、py();CDeepCopyoperator=(constCDeepCopy&r);赋值运算符函数;voidwriteToFile(char*);maincpp#include“CDeepCopyh“CDeepCopy:CDeepCopy()deletep;CDeepCopy:CDeepCopy(intk)n=k;P=newintn;构造函数实现CDeepCopyCDeepCopy:operator=(constCDeepCopyr)赋值运算符函数实现*333*666*intmain()CDeepCopya(2),d(3);aP0=1;dP0=666;对象 a,d 数组元素的赋值CDeepCo
25、pyb(3);aP0=88;b=a;调用赋值运算符函数 coutbP0;显示内层局部对象的数组元素coutdp0;显示 d 数组元素ap0的值 cout“dfadeaway;n“;coutaP0;显示 a 数组元素 aP0的值writeToFile(“);return0;(分数:2.00)_正确答案:(正确答案:n=rn;把对象 r 字符长度赋值给 n deletep;删除动态数组 p p=newintn; 给动态数组 p 分配空间为 n for(inti=0;in;i+) 遍历对象 r 中的数组 p pi=rpi; 把 rpi赋值给 pi return*this;返回被赋值的对象)解析:解析:主要考查考生对运算符重载的掌握,由注释可知此处要实现赋值运算符函数。要重载的运算符是“=”,该类的成员是动态数组 p,数组元素个数为 n,因此先释放原来的动态数组,再分配空间,然后逐个复制元素即可。