一、选择题 7. 有如下程序:
#include <iostream>
using namespace std;
class AA {
public:
virtual void f(){cout<<"AA";}
};
class BB:public AA{
public:
BB(){cout<<"BB";}
};
class CC:public BB{
public:
virtual void f() {BB::f(); cout<<"CC";}
};
int main(){
AA aa, *p;
BB bb;
CC cc;
p=&cc;
p->f();
return 0;
}
执行上面的程序将输出______。
A.BBAACC B.AABBCC C.BBAABBCC D.BBBBAACC
A B C D
10. 有如下程序
#include<iostream.h>
void main()
{ char ch[2][5]={"6937", "8254"},*p[2];
int i,j,s=0;
for(i=0;i<2;i++)p[i]=ch[i];
for(i=0;i<2;i++)
for(j=0;p[i][j]>'\0';j+=2)
s=10*s+p[i][j]='0';
cout<<s;}
该程序的输出结果是______。
A.69825 B.63825 C.6385 D.693825
A B C D
C
[解析] 该题主要要搞清楚以下几点:①定义了一个指针数组char*p[2]后,程序中第一个循环“for(i=0;i<2;i++)p[i]=ch[i]”的作用是使指针数组的p[0]元素(它本身是一个指针)指向了二维数组ch的第一行字符串,并使指针数组的p[1]元素指向了二维数组ch的第二行字符串,这样,就使指针数组p和二维数细ch建立起了一种对应关系,以后对二维数组ch的某个元素的引用就有两种等价的形式:ch[i][j]或p[i][j]。②对二维数组ch的初始化,使其第一行ch[0]中存入了字符串“6937”,第二行ch[1]中的内容为字符串“8254”。③程序中第二个循环中的循环体“s=s*10+p[i][j]='0'”的功能是这样的,每执行一次,将s中的值乘以10(即将s中的数值整体向左移动一位,并在空出来的个位上添一个0),再将当前p[i][j]中的字符量转换为相应的数字,然后把这个数字加到s的个位上。④注意到内层循环的循环条件p[i][j]>'\0'是指p[i][j]中的字符只要不是字符串结束标志'\0'就继续循环,语句j+=2;是使下标j每次增加2,即一个隔一个地从p[i]所指向的字符串中取出字符。经过上述解析后,不难看出,该程序首先从p[0]所指向的字符串“6937”中一个隔一个地取出字符,分别是“6”和“3”,然后从p[1]所指向的字符串“8254”中一个隔一个地取出字符,分别是“8”和“5”,同时经过转换和相加运算后,结果s中的值应该是6385。
11. 计算斐波那契数列第n项的函数定义如下:
int fib(int n){
if (n==0)return 1;
else if(n==1) return 2;
else return fib(n=1)+fib(n=2);
}
若执行函数调用表达式fib(2),函数fib被调用的次数是
。
A B C D
C
[解析] 针对递归调用的含义。当n为2时有fib(0),fib(1),fib(2)被调用,且fib(0),fib(1)时调用结束,即共3次。
15. 有以下类定义
class MyClass
{
private:
int id;
char gender,
char*phone;
public:
MyClass():id(0),gender('#'),phone(NULL){}
MyClass(int no,char ge='#',char*ph=NUl1.)
{id=no;gende=ge;phone=ph;}
};
下列类对象定义语句中错误的是______。
A.MyClass myObj; B.MyClass myObj(11,"13301111155"); C.MyClass myObj(12,'m'); D.MyClass myObj(12);
A B C D
B
[解析] 本题考查构造函数的重载和默认参数的使用。只要生成对象,类中就必须要有相应的构造函数供其调用。选项B,提供的实参分别是int和char*,没有相应的构造函数供其调用,是错误的。
17. 有如下程序:
#include<iostream>
using namespace std;
class XA{
int a;
public:
static int b;
XA(int aa):a(aa){b++;}
~XA(){}
int get(){return a;}
};
int XA::b=0
int main(){
XA dl(1),d2(3);
cout<<d1.get()+d2.get()+XA::b<<endl;
return 0;
}
运行时的输出结果是______。
A B C D
C
[解析] 每调用一次get函数时,对新的类A对象进行一次实例化,调用一次构造函数,类A的静态成员变量b便加1。
20. 有如下程序:
#include<iostream>
using namespace std;
class Base {
public:
void output() {cout<<1;}
virtual void Print() {cout<<'B';}
};
class Derived: public Base {
public:
void output() {cout<<2;}
void Print() {cout<<'D';}
};
int main()
Base *ptr=new Derived;
ptr->output();
ptr->Print();
delete ptr;
return 0;
}
执行这个程序的输出结果是______。
A B C D
B
[解析] 在某基类中声明为virtual并在一个或多个派生类中被重新定义的成员函数,本题中定义了一个指向派生类对象的基类指针ptr,执行ptr->output后,会执行基类的output函数,输出1,由于Print是虚函数,所以ptr->Print()会执行派生类的print,即输出D,所以本题答案为B。
22. 已知函数模板定义如下:
template<class T>
T min(T x, T y)
{
return x<y? x:y;
}
下列叙述中,错误的是______。
A.该函数模板有一个模板参数 B.T类型所允许的类型范围应提供有意义的<运算符操作 C.该函数模板生成的模板函数中,参数和返回值的类型可以不同 D.该函数模板可以生成模板函数double min(double, double)
A B C D
C
[解析] 该函数模板有一个模板参数T,选项A正确;由于在函数体中需要比较函数两个参数x、y的大小,所以T类型必须能够提供有意义的<运算符操作,选项B正确;double具有有意义的<运算符操作,所以可以生成模板函数double min(double,double),选项D正确;在该函数模板中,函数的参数和返回值类型都是T,所以参数和返回值的类型必须是一样的,选项C错误。答案为C选项。
31. 有如下程序:
#include<iostream>
using namespace std;
class B{
public:
virtual void show( ){cout<<"B";}
};
class D:public B{
public:
void show( ){cout<<"D";}
};
void funl(B*ptr){ptr->show( );}
void fun2(B&ref);ref.show( );}
void fun3(B b){b.show( );}
int nlain( ){
B b,*P=Dew D;
D d;
funl(p);
fun2(b);
fun3(d);
return 0;
}
程序的输出结果是______
A B C D
C
[解析] 基类指针可以指向派生类对象,在对象作为参数传递时,是通过“传值调用”传递给函数的,是单向传递。使用对象指针对函数参数进行传递时,是通过“传址调用”传递给函数的,即函数的形参对象和实参对象指针变量指向同一内存地址;使用对象引用作为函数参数时,也是通过“传址调用”传递给函数的。funl(p)传递的是类D对象的地址,所以调用类D的是show( ),fun2(b)调用的和传递的都是类B的对象引用,所以调用类B的show( )。调用’fun3(d)时,由于void fun3(B b)传递的虽然是D类对象,但是形参是B类对象,所以调用基类B的show( )。
34. 有如下类声明:
class SAMPLE
{
int n;
public:
SAMPLE(int i=0):n(i) {}
void setValue(int n0);
};
下列关于getValue成员函数的定义中,正确的是______。
A.SAMPLE:: setValue(int n0) {n=n0; } B.void SAMPLE:: setValue(int n0) {n=n0;} C.void setValue(int n0) {n=n0;} D.setValue(int n0) {n=n0;}
A B C D
B
[解析] 本题考查在类外定义类的成员函数,需要使用作用域限定符“::”,属于基础知识,本题答案为B。
38. 有如下程序:
#include<iostream>
using namespace std;
class AA{
public:
AA(){cout<<'1';}
};
class BB:public AA{
int k;
public:
BB():k(0){cout<<'2';}
BB(int n):k(n){cout<<'3';}
};
int main(){
BB b(4),c;
return 0;
}
运行时的输出结果是______。
A B C D
A
[解析] 本题考查构造函数重载,以及派生类构造函数的调用。题中,生成派生类对象b时,先要调用基类AA类构造函数,输出'1',再调用BB类的第2个构造函数,输出'3'。生成派生类对象c时,先要调用基类AA类构造函数,输出'1',再调用BB类的第1个构造函数,输出'2'。故最终输出结果为:1312。
二、基本操作题 1.
考生文件夹 使用VC++2010打开考生文件夹下“proj1”文件夹中的工程proj1.sln,该程序运行时有错,请改正其中的错误,使得程序正常运行,并使程序输出的结果为:
1
1
2
1
注意:不要改动main函数,不能增行或删行,电不能更改程序的结构,错误的语句在//******error******的下面。
#include<iostream.h>
class TestClass
{
//********error********
//********error********
const int j;
public:
TestClass()
{
//********error********
statiC int i=0;
cout<<++i<<endl;
cout<<j<<endl;
}
};
void main()
{
TestClass obj1;
TestClass obj2;
obj2.j+=obj1.j;
return;
}
(1)添加语句:public; (2)int j; (3)添加语句:j=1;
[解析] 本题程序的功能是输出1 1 2 1。解题思路从己定源程序的main主函数开始入手,程序通过类TestClass中成员函数实现题目中要求的输出。 (1)打开modi1.cpp,调试程序,显示错误提示为“modi1.cpp(22):error C2248:'j':cannot access private member declared in class 'TestClass'”,第1个标识下的i变量由于被定义为私有的,其他函数不可获得,这里应该是public型,所以在第1个标识下添加“public:”。 (2)程序中对于j的调用,说明j并不是常量,所以修改j的定义,将其定义为变量,而不是常变量,即修改第2个标识下语句为“int j;”。 (3)题目中要求调用对象,输出j的值为1。原程序中j变量的使用并没有赋初始化值,输出值为乱码,所以第三个标识下添加“j=1;”。
三、简单应用题 1.
考生文件夹 使用VC++2010打开考生文件夹下“proj2”文件夹中的工程proj2.sln,其中定义了多个类,但类不能达到输出要求,按照定义的输出修改函数,使得输出如下:
TestClass3
TestClass2
TestClass1
其中定义的类并不完整,按照要求完成下列操作,将类的定义补充完整。
(1)类TestClass2公共继承于TestClass1,请在注释//********1********后添加适当的语句。
(2)print函数为虚函数,请在注释//********2********后添加适当的语句。
(3)修改语句,使得p指定对象obj3,请在注释//********3********后添加适当的语句。
(4)修改语句,利用p调用print()函数,完成输出信息,注释//********4********后添加适当的语句。
注意:仅在函数指定位置添加语句,请勿改动主函数main与其他函数中的任何内容。
#include<iostream>
using namespace std;
class TestClass1
{
public:
void print(){
cout<<"TestClasS1"<<endl:
}
};
//********1********
Class TestClass2
{
public:
//********2********
void print()
{
cout<<"TestClass2"<<endl;
}
};
class TestClass3:public TestClass2
{
public:
void print()
{
cout<<"TestClass3"<<endl;
}
};
int main()
{
TestClass2 obj2;
TestClass3 obj3;
TestClass1* p;
obj2.print();
obj3.print();
//********3********
p=obj3;
//********4********
p.print();
return 0;
}
(1)将“class TestClass2”补充完整为:class TestClass2:publiC TestClass1 (2)将“void print()”补充完整为:virtual void print() (3)将“p=obj3;”修改为:p=&obj3; (4)将“p.print();”修改为:p->print();
[解析] 本题的功能是通过print虚函数将字符串输出。在VC环境下打开程序,根据题干给出的几条功能要求,对程序中给出注释下的内容逐个补全或修改。从已定源程序的main主函数开始入手,可以看出程序通过调用类和成员函数实现各种输出操作。 (1)题目1要求“类TestClass2公共继承于TestClass1”。从已有的类产生一个新的子类,成为类的派生。声明派生类的一般形式为:class派生类名:[继承方式]基类名。根据题目中的要求以及派生类的一般形式,第1个标识下添加语句“class TestClass2: public TestClass1”。 (2)题目2要求“print函数为虚函数”。在C++中,用virtual声明的函数为虚函数,因此第2个标识下的语句修改为“virtual void print()”。 (3)题目3要求“使得p指定对象obj3”。p为指针变量,obj3为类的对象,将一个指针变量指向另一个变量,只要把被指向的变量的地址赋给指针变量即可。取对象obj3地址的语句为&obj3,所以这里补全“p=&obj3;”。 (4)题目4要求“利用p调用print()函数”。C++中用"->"运算符实现成员访问,因此调用print()函数,应将第4个标识下修改为“p->print();”。
四、综合应用题 1. 使用VC++6.0打开
考生文件夹 下的源程序文件3.cpp。其中定义的类不完整,按要求完成下列操作,将类的定义补充完整。
(1)将文件以追加的方式打开。请在注释1后添加适当的语句。
(2)定义m、n为类TC的公有int型数据成员。请在注释2后添加适当的语句。
(3)定义p为类TC的数据成员指针,并指向类TC的数据成员m。请在注释3后添加适当的语句。
(4)定义p指向类TC的数据成员n。请在注释4后添加适当的语句。
注意:增加或者修改代码的位置已经用符号表示出来,请不要修改其他的程序代码。
试题程序:
#include<iostream.h>
#include<fstream>
#include<iomanip>
#include<cmath>
using namespace std;
void WriteFile(int x)
{
ofstream out1;
//********1********
out1.open("3.txt", );
out1 << x << ′ ′;
out1.close();
}
void ClearFile()
{
ofstream out1;
out1.open("3.txt");
out1.close();
}
class TC
{
public:
void disp()
{
cout << "m=" << m << endl;
WriteFile(m);
cout << "n=" << n << endl;
WriteFile(n);
}
//********2********
};
void main()
{
//********3********
ClearFile();
TC a;
a.*p=30;
//********4********
a.*p=45;
a.disp();
}
(1)将“out1.open("3.txt", );”补充完整为:out1.open("3.txt", ios_base::app);
(2)应添加int m,n;
(3)应添加int TC::*p=&(TC::m);
(4)应添加p=&(TC::n);
答案考生文件夹 [解析] 本题第1处要求“对文件以追加的方式打开”。文件输入输出方式的设置值,ios::app是以输出方式打开文件,写入的数据添加在文件末尾,即第1处的语句补全为“out1.open("3.txt", ios_base::app);”。第2处要求“定义m、n为类TC的公有int型数据成员”。只需在程序中的TC类中的public区域添加m、n的定义即可。即在第2处添加“int m,n;”。第3处要求“定义p为类TC的数据成员指针,并指向类TC数据成员m”。程序中类TC数据成员m为:TC::m,定义p为类TC的数据成员指针语句为:TC::*p,将其指向前面的数据成员m,即为“int TC::*p=&(TC::m);”。第4处要求“定义p指向类TC 数据成员n”。定义类TC 数据成员n的语句为TC::n,用p指向类TC数据成员n,添加的语句即“p=&(TC::n);”。