2021华南师范大学C++程序设计(918)硕士研究生考试试题 以及 详细答案解析

2021华南师范大学C++程序设计(918)硕士研究生考试试题 以及 详细答案解析

试题

一、单项选择题(共 15 道题,每道题 3 分,共 45 分)

1while(!E)里的(!E)条件等价于 

A、E==0 	B、E!=0 	C、E==1 	D、E!=1 

2、略

3、下列不能正确赋值的是?

A、char str[5] = “good!”; B、char str[] = “good!”;

C、char str[8] = “good!”; D、char str[5] = {‘g’,‘o’,‘o’,‘d’,’!’};

4、若有 int i=100;下列定义引用正确的是?

A、int &a=i; B、int &a=100; C、int &a=&i; D、int a = &i;

5、假设有 class A{private: int aa,bb; public:A(int aa,int bb){a = aa–;b = a*bb;}},则 A c(4,5);cout<<c.a<<","<<c.b;

输出?

A、3,15 B、15,3 C、4,20 D、20,4

6、对于指向同一块连续内存的两个指针变量,不能执行哪个运算?

A、< B、= C、+ D、-

7、下列哪个不是类的成员函数?

A、构造函数 B、析构函数 C、友元函数 D、赋值函数

8、下列哪个不能作为重载函数调用的依据?

A、参数格式 B、参数类型 C、函数名 D、函数类型

9、下列可以实现动态联绑的是?

A、通过对象调用虚函数 B、通过指针或引用调用虚函数

C、通过对象调用静态函数 D、通过指针或引用调用静态函数

10、公共派生类不能直接访问从基类中继承过来的成员,则该成员一定是

A、私有成员 B、公有成员 C、保护成员 D、私有成员或保护成员

11、类模板的实例化是将类模板实例化成一个

A、对象 B、函数 C、类 D、抽象类

12、cout 是哪个类的实例化对象

A、ostream B、fstream C、stdout D、stdin

13、MyA 复制构造函数是?

A、MyA() B、MyA(MyA *) C、MyA(MyA &) D、MyA(MyA)

14、静态成员函数没有()?

A、返回值 B、this 指针 C、指针参数 D、返回类型

15、定义虚基类是为了?

A、简化代码 B、提高程序效率 C、消除二义性 D、实现多态性

二、运行结果题(共 5 小题,每小题 4 分,一共 20 分)

1、

#include<iostream> 
using namespace std; 
int main() {
	int x=1,a=0,b=0; 
	switch(x) {
		case 0:b++; 
        case 1:a++; 
        case 2:a++;b++; 
	}
	cout<<a<<","<<b; 
}

2、

#include<iostream> 
using namespace std; 
int a = 100; 
int f() {
	static int a = 10; 
	return ++a; 
}
int main() {
	cout<<f()<<","<<a; 
}

3、

#include<iostream> 
using namespace std; 
class Base {
protected: 
	Base(){cout<<"A";} 
	Base(char c){cout<<c;} 
}; 
class D:protected Base {
public: 
	D(char c){cout<<c;} 
}; 
int main() {
	D d('B'); 
}

4、

#include<iostream> 
using namespace std; 
class A {
public: 
	A(){cout<<"1";} 

}; 
int main() {
	A a,b[2],*p[2]; 
}

5、

#include<iostream> 
using namespace std; 
class One {
public: 
	virtual void f(){ 
		cout<<"1"; 
	}
}; 
class Two:public One {
public: 
	Two(){cout<<"2";} 
}; 
class Three:public Two {
public: 
	virtual void f(){Two::f();cout<<"3";} 
}; 
int main() {
	One o,*p; 
	Two t2; 
	Three t3; 
	p=&t3; p->f(); 
}

三、代码填空题(共 10 个空,每空 3 分,共 30 分)

1、找出 M 行 N 列数组(M=3,N=4)里每行最大值并显示

#include<iostream> 
using namespace std; 
int main(){
	____①____; 
	int a[M][N] ={{1,3,5,7},{9,2,4,6},{8,0,11,12}}; 
	for(___②___;i<M;i++){
		int t=0; 
		for(____③___;j<N;j++){
			if(___④___) 
				____⑤____ 
		}
	cout<<i+1<<"行,"<<t+1<<"列,值:"<<a[i][t]; 
	}
}


2、完善类 A

class A {
private: 
	___⑥___ 
	int n; 
public: 
	A(int nn):n(nn){ 
		if(n==0){a = 0;} 
		else{a = new int[n];} 
	}
	_____⑦_____//(析构并删除动态数组) 
}; 

3、

#include<iostream> 
using namespace std; 
class Vehicle{
protected: 
	int size; 
	int speed; 
public: 
	void setSpeed(int s){speed = s;} 
	___⑧___ getSpeedLevel(){ return speed/10;} 
}; 
class Car:public Vehicle {
public: 
	int getSpeedLevel(){ return speed/5;} 
}; 
class Truck:public Vehicle {
public: 
	int getSpeedLevel(){ return speed/15;} 
}; 
int maxSpeedLevel(Vehicle __⑨__,Vehicle __⑩__) 
{
	if(v1.getSpeedLevel()>v2.getSpeedLevel()) return 1; 
	else return 2; 
}
int main() 
{
	Truck t; 
	Car c; 
	t.setSpeed(130); c.setSpeed(60); 
	cout<<maxSpeedLevel(t,c)<<endl; //此处结果输出 2 
}

四、简答题(共 3 道题,每道 5 分,共 15 分)

1、什么是模板函数?模板函数有什么作用?

2、什么情况下必须定义自己的复制构造函数?

3、为什么要定义虚析构函数?

五、程序设计题(共 4 道题,每道 10 分,共 40 分)0

1、假设 ABCD X E = DCBA,其中 A,B,C,D,E 分别代表不同的数字、编程找出 A,B,C,D,E 分别是

多少?

2、定义一个函数 char * itos(int n); 实现整形转字符。

3、定义一个复数类 CComplex,定义一个两个参数的构造函数(其中一个有默认值) 显示 ,

函数 Show,重载+(使用成员函数) 用 main 函数测试。 ,并

4、从键盘连续输入多行字符保存到 D:\a.txt 文件中,并从文件中读取显示出来。

答案:

选择题

1.A2.3.A
4.A5.C6.C
7. C8.D9.B
10.A11.C12.A
13.C14.B15.C

运行结果题

1. 2,12. 11,1003. ab4. 1115. 2213

代码填空

#include<iostream> 
using namespace std; 
int main(){
	int M=3,N=4; 
	int a[M][N] ={{1,3,5,7},{9,2,4,6},{8,0,11,12}}; 
	for(int i =0;i<M;i++){
		int t=0; 
		for(int j = 0;j<N;j++){
			if(a[i][j]>a[i][t]) 
				t=j; 
		}
	cout<<i+1<<"行,"<<t+1<<"列,值:"<<a[i][t]<<endl; 
	}
}
#include<iostream> 
using namespace std; 
class A {
private: 
	int *a;
	int n; 
public: 
	A(int nn):n(nn){ 
		if(n==0){a = 0;} 
		else{a = new int[n];} 
	}
    ~A(){delete []a;}//(析构并删除动态数组) 
}; 
int main(){
	A a(0),b(9);
    cout<<"ok!";
    
}
#include<iostream> 
using namespace std; 
class Vehicle{
protected: 
	int size; 
	int speed; 
public: 
	void setSpeed(int s){speed = s;} 
	virtual int getSpeedLevel(){ return speed/10;} 
}; 
class Car:public Vehicle {
public: 
	int getSpeedLevel(){ return speed/5;} 
}; 
class Truck:public Vehicle {
public: 
	int getSpeedLevel(){ return speed/15;} 
}; 
int maxSpeedLevel(Vehicle &v1,Vehicle &v2) 
{
	if(v1.getSpeedLevel()>v2.getSpeedLevel()) return 1; 
	else return 2; 
}
int main() 
{
	Truck t; 
	Car c; 
	t.setSpeed(130); c.setSpeed(60); 
	cout<<maxSpeedLevel(t,c)<<endl; //此处结果输出 2 
}


简答题

1、什么是模板函数?模板函数有什么作用?

模板函数不是实在的函数,编译器不能为其生成可执行代码。

作用是:定义函数功能模块,当其具体执行时,会根据传递的实参来决定其功能,大大的提高了复用性,减少重复造轮子

2、什么情况下必须定义自己的复制构造函数?
复制构造函数被调用的三种情况分别是:

  1. 用一个对象初始化另一个对象时
  2. 当用对象作为函数参数传递时
  3. 当函数返回对象时
    如果复制构造有指针进行复制时就需要自己定义复制构造函数,因为默认的复制构造函数会使两个指针指向同一个地址空间,对其中任何一个的修改都会变成对另一个的修改,而且在一个对象析构时,另一个对象也会丧失原有的地址空间。

3、为什么要定义虚析构函数?

对象销毁时,需要调用析构函数。在多态调用时,是用基类的指针访问派生类的对象。如果析构函数是非虚函数,则基类指针只能访问基类的析构函数,而不能访问派生类的析构函数,导致派生类对象销毁时,没有调用派生类的析构函数,只是调用了基类的析构函数。如果把析构函数定义成虚函数,则可克服这个问题。

程序设计题

1.https://blog.csdn.net/weixin_43744732/article/details/120668175

2.https://blog.csdn.net/weixin_43744732/article/details/120668745

3.https://blog.csdn.net/weixin_43744732/article/details/120669328

4.https://blog.csdn.net/weixin_43744732/article/details/120669627

解析

选择题


 1while(!E)里的(!E)条件等价于 (A)

A、E==0 	B、E!=0 	C、E==1 	D、E!=1while中不为false时,就会一直循环,所以!E是跳出循环的条件也就是false

这题同时考察了ture和false的数字分别是几。ex:ture(1),false(0)

所以 E==false就是E==0

!称为逻辑非运算符。执行逻辑 NOT 操作,用来逆转操作数的逻辑状态。如果条件为真则逻辑非运算符将使其为假。

3、下列不能正确赋值的是? (A)

A、char str[5] = “good!”; B、char str[] = “good!”;

C、char str[8] = “good!”; D、char str[5] = {‘g’,‘o’,‘o’,‘d’,’!’};

good!这里有五个字符,char数组最后会加’\0’,所以长度要加一,char str[6] = “good!”;

4、若有 int i=100;下列定义引用正确的是? (A)

A、int &a=i; B、int &a=100; C、int &a=&i; D、int a = &i;

A:正确的引用方式蓝豹子p168,a是i的别名,a与i的地址关联起来,公用一个内存单元

B:引用类型本质是关联地址,公用同个内存单元,int &a=100;明显不行,除非const int &a=100;,前面加上const就是合法的,此时系统会生成一个存放100的临时变量,并将临时变量作为a 的初值。且由于a声明为常量,因此只能被引用而无法被赋值。

C:没有这样的写法,两个引用相互关联应该int &a = i;int &j = a;这样a和j就关联起来了

D:&是一种代表引用的符号,只放前面,像A就是正确的写法,有指针除外ex:int *p ; p =&i;可以这样。

5、假设有 class A{private: int aa,bb; public:A(int aa,int bb){a = aa–;b = a*bb;}},则 A c(4,5);cout<<c.a<<","<<c.b;

输出? (C)

A、3,15 B、15,3 C、4,20 D、20,4

A的构造函数,a=aa–;--在aa后面表示先复制后减一,故a=4,b=a*bb;此时a=4,bb=5。故b=20;

6、对于指向同一块连续内存的两个指针变量,不能执行哪个运算? ©

A、< B、= C、+ D、-

不能进行运算“+”运算。

类型相同的两个指针变量之间可以进行<(小于)、=(等于)、-(减法)运算。

1、“<(小于)”运算在两个同类型的指针间可以比较大小,比较原则应该是按照实际内存的高低位比较的

2、“=(等于)”是对于类型相同的两个指针变量之间常规运算。

3、“+”运算是不可以的,因为两个指针相加什么都得不到,所以规定不允许相加。

4、“-(减法)”运算两个相同指针变量相减可以获得在之间相隔的同类型元素个数(在某个类型的数组中的应用)。

7、下列哪个不是类的成员函数? ©

A、构造函数 B、析构函数 C、友元函数 D、赋值函数

构造函数,析构函数,赋值函数都是类成员函数,友元函数的实现是在类外部实现的,友元函数本身不属于类函数。

8、下列哪个不能作为重载函数调用的依据? (D)

A、参数格式 B、参数类型 C、函数名 D、函数类型

重载函数调用的依据有函数名、函数的参数类型、参数个数。

函数中参数的个数和类型,个数要保证在有默认参数时个数也是不同的,根据返回值无法辨认。

9、下列可以实现动态联绑的是? (B)

A、通过对象调用虚函数 B、通过指针或引用调用虚函数

C、通过对象调用静态函数 D、通过指针或引用调用静态函数

C++的函数调用默认不使用动态绑定。要触发动态绑定,必须满足两个条件:

  1. 只有指定为虚函数的成员函数才能进行动态绑定
  2. 必须通过基类类型的引用或指针进行函数调用

因为每个派生类对象中都拥有基类部分,所以可以使用基类类型的指针或引用来引用派生类对象

10、公共派生类不能直接访问从基类中继承过来的成员,则该成员一定是 (A)

A、私有成员 B、公有成员 C、保护成员 D、私有成员或保护成员

image-20211208210847086

11、类模板的实例化是将类模板实例化成一个 (C)

A、对象 B、函数 C、类 D、抽象类

蓝豹子p307:编译器首先将模板的实际参数值带入类模板,生成一个可真正使用的

12、cout 是哪个类的实例化对象 (A)

A、ostream B、fstream C、stdout D、stdin

A:输出流类

B:输入输出文件流类

C和D好像是c里面的,我也不太清楚

13、MyA 复制构造函数是? (C)

A、MyA() B、MyA(MyA *) C、MyA(MyA &) D、MyA(MyA)

14、静态成员函数没有()? (B)

A、返回值 B、this 指针 C、指针参数 D、返回类型

蓝豹子p245:静态成员函数是为类服务的,它最大特点就是没有隐含的this指针

静态成员函数只能访问静态成员变量–>静态成员函数没有this指针

15、定义虚基类是为了?

A、简化代码 B、提高程序效率 C、消除二义性 D、实现多态性

image-20211208212408168

运行结果题

image-20211208212844732

image-20211208213216111

image-20211208213454812

image-20211208214031811

image-20211208214756911

代码填空题

image-20211208215026109

image-20211208215528887

image-20211211175401241

简答题

1、什么是模板函数?模板函数有什么作用?

模板函数不是实在的函数,编译器不能为其生成可执行代码。

作用是:定义函数功能模块,当其具体执行时,会根据传递的实参来决定其功能,大大的提高了复用性,减少重复造轮子

2、什么情况下必须定义自己的复制构造函数?
复制构造函数被调用的三种情况分别是:

  1. 用一个对象初始化另一个对象时
  2. 当用对象作为函数参数传递时
  3. 当函数返回对象时

如果复制构造有指针进行复制时就需要自己定义复制构造函数,因为默认的复制构造函数会使两个指针指向同一个地址空间,对其中任何一个的修改都会变成对另一个的修改,而且在一个对象析构时,另一个对象也会丧失原有的地址空间。

3、为什么要定义虚析构函数?

对象销毁时,需要调用析构函数。在多态调用时,是用基类的指针访问派生类的对象。如果析构函数是非虚函数,则基类指针只能访问基类的析构函数,而不能访问派生类的析构函数,导致派生类对象销毁时,没有调用派生类的析构函数,只是调用了基类的析构函数。如果把析构函数定义成虚函数,则可克服这个问题。

程序设计题

#include <iostream>

using namespace std;
//1. 编程找出满足ABCD*E=DCBA的互不相同A B C D E的五个数字
//互不相同A B C D E

//purpose:bdifferent这个函数是来判断ABCD是否各不相同
bool bdifferent(int aryList[4]){
    /*
    这里采用了数组的方式来表示nArr[0]就代表A,nArr[1]就代表B,nArr[2]就代表C,nArr[3]就代表D
    代码中用了最朴素的方式来看ABCD是否各个都不同。这里提供另一种思路,但时间复杂度高不如最朴素的
    for(int i=0;i<4;i++){
        int j=0;
        for(j=i;j<4;j++){
            if(aryList[i]==aryList[j]){
            return true
            }
        }
    }
    return false
    */
 	
    if(aryList[0]==aryList[1]||aryList[0]==aryList[2]||aryList[0]==aryList[3]||aryList[1]==aryList[2]||aryList[1]==aryList[3]||aryList[2]==aryList[3])  return true;
    return false;
}
//purpose:bdifferentE这个函数是来判断E是否和ABCD不相同
bool bdifferentE(int aryList[4],int nE){
     //遍历输出ABCD和E相比
 	 for(int i=0;i<4;i++){
         if(aryList[i]==nE){
             return true;
         }
    }
    return false;
}
//purpose:打印ABCDE
void aryprint(int aryList[4],int nE){
    cout<<"ABCDE为:"<<endl;
    for(int i=0;i<4;i++){
        cout<<aryList[i]<<" ";
    }
    cout<<nE<<endl;
}

int main()
{
    int aryList[4];//创建一个数组用于存放ABCD
    for(int i=1000;i<9999;i++){//循环获取全部的四位数
        int y = 3;//用于方便表示数组下标arrList[3]就是表示D
        int nTmp1 = i;//获取当前四位数
        //purpose:这个循环用于将i去摸获取最后一位数放入数组中,然后对nTmp1除十,直到四位数都放入数组中
        while(nTmp1!=0){
            aryList[y]=nTmp1%10;
            nTmp1/=10;
            y--;
        }
        //purpose:判断当前数组ABCD是否各不相同,如果相同则continue进入下一个循环,不同则继续执行下面的代码
        if(bdifferent(aryList)){
            continue;
        }
        //purpose:将数字倒序放入nTmp3,nTmp3的数表示DCBA
        int nTmp2 = i;
        int nTmp3 = 0;
        while(nTmp2!=0){
            int nNum=nTmp2%10;
            nTmp2/=10;
            nTmp3 = nTmp3*10 + nNum;
        }
        //purpose:模拟ABCD*E=DCBA
        for(int e=1;e<=9;e++){
            if((i*e)==nTmp3){
                if(bdifferentE(aryList,e)){
                    continue;
                }
                aryprint(aryList,e);
                break;
            }

        }
    }
    return 0;
}




  • 11
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 19
    评论
评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值