目录
一、选择题
二、编程题
三、选择题题解
四、编程题题解
一、选择题
1、下列一段 C++ 代码的输出结果是()
#include <iostream>
class Base
{
public:
int Bar(char x)
{
return (int)(x);
}
virtual int Bar(int x)
{
return (2 * x);
}
};
class Derived : public Base
{
public:
int Bar(char x)
{
return (int)(-x);
}
int Bar(int x)
{
return (x / 2);
}
};
int main(void)
{
Derived Obj;
Base *pObj = &Obj;
printf("%d,", pObj->Bar((char)(100)));
printf("%d,", pObj->Bar(100));
return 0;
}
A. 100,-100
B. 100,50
C. 200,-100
D. 200,50
2、关于函数的描述正确的是()
A. 虚函数是一个static型的函数
B. 派生类的虚函数与基类的虚函数具有不同的参数个数和类型
C. 虚函数是一个非成员函数
D. 基类中说明了虚函数后,派生类中起对应的函数可以不必说明为虚函数
3、代码执行后,a和b的值分别为?
// 32位环境下
class Test
{
public:
int a;
int b;
virtual void fun() {}
Test(int temp1 = 0, int temp2 = 0)
{
a=temp1 ;
b=temp2 ;
}
int getA()
{
return a;
}
int getB()
{
return b;
}
};
int main()
{
Test obj(5, 10);
// Changing a and b
int* pInt = (int*)&obj;
*(pInt+0) = 100;
*(pInt+1) = 200;
cout << "a = " << obj.getA() << endl;
cout << "b = " << obj.getB() << endl;
return 0;
}
A. 200 10
B. 5 10
C. 100 200
D. 100 10
4、当一个类的某个函数被说明为virtual,则在该类的所有派生类中的同原型函数_____?
A. 只有 被重新说明时才识虚函数
B. 只有被重新说明为virtual时才是虚函数
C. 都不是虚函数
D. 都是虚函数
5、下面有关虚函数和非虚函数的区别说法错误的是?
A. 子类的指针访问虚函数访问的是子类的方法
B. 子类的指针访问非虚函数访问的是子类的方法
C. 父类的指针访问虚函数访问的是父类的方法
D. 父类的指针访问非虚函数访问的是父类的方法
6、下列程序的输出结果:
#include <iostream>
using namespace std;
class A
{
public:
void print()
{
cout << "A:print()";
}
};
class B: private A
{
public:
void print()
{
cout << "B:print()";
}
};
class C: public B
{
public:
void print()
{
A:: print();
}
};
int main()
{
C b;
b.print();
return 0;
}
A. A:print()
B. B:print()
C. 编译出错
7、以下关于C++的描述中哪一个是正确的()
A. 任何指针都必须指向一个实例
B. 子类指针不可以指向父类实例
C. 任何引用都必须指向一个实例
D. 引用所指向的实例不可能无效
8、下面关于多态性的描述,错误的是()
A. C++语言的多态性分为编译时的多态性和运行时的多态性
B. 编译时的多态性可通过函数重载实现
C. 运行时的多态性可通过模板和虚函数实现
D. 实现运行时多态性的机制称为动态绑定
9、写出下面程序的输出结果
class A
{
public:
void FuncA()
{
printf( "FuncA called\n" );
}
virtual void FuncB()
{
printf( "FuncB called\n" );
}
};
class B : public A
{
public:
void FuncA()
{
A::FuncA();
printf( "FuncAB called\n" );
}
virtual void FuncB()
{
printf( "FuncBB called\n" );
}
};
void main( void )
{
B b;
A *pa;
pa = &b;
A *pa2 = new A;
pa->FuncA(); ( 3)
pa->FuncB(); ( 4)
pa2->FuncA(); ( 5)
pa2->FuncB();
delete pa2;
return 0;
}
A. FuncA called FuncB called FuncA called FuncB called
B. FuncA called FuncBB called FuncA called FuncB called
C. FuncA called FuncBB called FuncAB called FuncBB called
D. FuncAB called FuncBB called FuncA called FuncB called
10、在32位环境下,以上程序的输出结果是?
#include<iostream>
using namespace std;
class Base
{
public:
virtual int foo(int x)
{
return x * 10;
}
int foo(char x[14])
{
return sizeof(x) + 10;
}
};
class Derived: public Base
{
int foo(int x)
{
return x * 20;
}
virtual int foo(char x[10])
{
return sizeof(x) + 20;
}
} ;
int main()
{
Derived stDerived;
Base *pstBase = &stDerived;
char x[10];
printf("%d\n", pstBase->foo(100) + pstBase->foo(x));
return 0;
}
A. 2000
B. 2004
C. 2014
D. 2024
二、编程题
1、完全数计算 题目链接
2、扑克牌大小 题目链接
三、选择题题解
1、下列一段 C++ 代码的输出结果是()
#include <iostream>
class Base
{
public:
int Bar(char x)
{
return (int)(x);
}
virtual int Bar(int x)
{
return (2 * x);
}
};
class Derived : public Base
{
public:
int Bar(char x)
{
return (int)(-x);
}
int Bar(int x)
{
return (x / 2);
}
};
int main(void)
{
Derived Obj;
Base *pObj = &Obj;
printf("%d,", pObj->Bar((char)(100)));
printf("%d,", pObj->Bar(100));
return 0;
}
A. 100,-100
B. 100,50
C. 200,-100
D. 200,50
正确答案:B
题解:
首先我们观察题目,父类与子类中都有两个叫bar的函数,其中形参为int的是虚函数,并进行了重写,形参为char的与这个虚函数构成重载;我们在看主函数中,我们实例化了一个子类对象,并用父类指针指向它,然后我们调用父类char类的那个接口,返回100;接着我们调用int那个接口,这个接口声明成了虚函数,又是用父类的指针调用,构成多态,可是该指针原本指向的是一个子类对象,因此这里调用子类的那个虚函数,返回打印50;故选B;
2、关于函数的描述正确的是()
A. 虚函数是一个static型的函数
B. 派生类的虚函数与基类的虚函数具有不同的参数个数和类型
C. 虚函数是一个非成员函数
D. 基类中说明了虚函数后,派生类中起对应的函数可以不必说明为虚函数
正确答案:D
题解:
A选项,虚函数不可能是静态成员函数,因为静态成员函数没有this指针;B选项,虚函数的重写必须满足返回值相同,函数名相同,函数参数相同(除了协变与析构);C选项,虚函数必须为成员函数,非成员函数没有this指针;D选项,正确;
3、代码执行后,a和b的值分别为?
class Test
{
public:
int a;
int b;
virtual void fun() {}
Test(int temp1 = 0, int temp2 = 0)
{
a=temp1 ;
b=temp2 ;
}
int getA()
{
return a;
}
int getB()
{
return b;
}
};
int main()
{
Test obj(5, 10);
// Changing a and b
int* pInt = (int*)&obj;
*(pInt+0) = 100;
*(pInt+1) = 200;
cout << "a = " << obj.getA() << endl;
cout << "b = " << obj.getB() << endl;
return 0;
}
A. 200 10
B. 5 10
C. 100 200
D. 100 10
正确答案:A
题解:
这里有个小坑,可能很多人会选C选项,这题实际上有个虚函数,既然类中声明了虚函数,那必然有虚表指针,而虚表指针一般都放在类的起始位置;因此我们取类的地址并强制转换成int*类型,指向的就是开头的虚表指针,我们首先将虚表指针改为100;在将第二个元素a改为200;构造中b初始化为10;故此题选A;
4、当一个类的某个函数被说明为virtual,则在该类的所有派生类中的同原型函数_____?
A. 只有 被重新说明时才识虚函数
B. 只有被重新说明为virtual时才是虚函数
C. 都不是虚函数
D. 都是虚函数
正确答案:D
题解:
只要在父类中声明为virtual函数,那么其所有子类中的同型函数都为虚函数;
5、下面有关虚函数和非虚函数的区别说法错误的是?
A. 子类的指针访问虚函数访问的是子类的方法
B. 子类的指针访问非虚函数访问的是子类的方法
C. 父类的指针访问虚函数访问的是父类的方法
D. 父类的指针访问非虚函数访问的是父类的方法
正确答案:C
题解:
C选项中说父类的指针访问虚函数必然是访问父类的方法,其实也不一定,要是构成多态了呢?可能访问子类的同型函数;
6、下列程序的输出结果:
#include <iostream>
using namespace std;
class A
{
public:
void print()
{
cout << "A:print()";
}
};
class B: private A
{
public:
void print()
{
cout << "B:print()";
}
};
class C: public B
{
public:
void print()
{
A:: print();
}
};
int main()
{
C b;
b.print();
return 0;
}
A. A:print()
B. B:print()
C. 编译出错
正确答案:C
题解:
仔细观察,在B继承父类时,是私有继承方式,对子类是不可见的,因此,无法在C类中调用A类的print函数;故编译错误,选C;
7、以下关于C++的描述中哪一个是正确的()
A. 任何指针都必须指向一个实例
B. 子类指针不可以指向父类实例
C. 任何引用都必须指向一个实例
D. 引用所指向的实例不可能无效
正确答案:C
题解:
A选项,可以有指向空的指针;B选项,可通过强制类型转换或dynamic_cast的方式将子类指针指向父类;C选项,描述正确;D选项,若引用的对象空间是在堆上动态申请的,那么该空间析构时,引用所指向的实例无效;
8、下面关于多态性的描述,错误的是()
A. C++语言的多态性分为编译时的多态性和运行时的多态性
B. 编译时的多态性可通过函数重载实现
C. 运行时的多态性可通过模板和虚函数实现
D. 实现运行时多态性的机制称为动态绑定
正确答案:C
题解:
C选项,模板与多态没有任何关系;
9、写出下面程序的输出结果
class A
{
public:
void FuncA()
{
printf( "FuncA called\n" );
}
virtual void FuncB()
{
printf( "FuncB called\n" );
}
};
class B : public A
{
public:
void FuncA()
{
A::FuncA();
printf( "FuncAB called\n" );
}
virtual void FuncB()
{
printf( "FuncBB called\n" );
}
};
void main( void )
{
B b;
A *pa;
pa = &b;
A *pa2 = new A;
pa->FuncA(); ( 3)
pa->FuncB(); ( 4)
pa2->FuncA(); ( 5)
pa2->FuncB();
delete pa2;
return 0;
}
A. FuncA called FuncB called FuncA called FuncB called
B. FuncA called FuncBB called FuncA called FuncB called
C. FuncA called FuncBB called FuncAB called FuncBB called
D. FuncAB called FuncBB called FuncA called FuncB called
正确答案:B
题解:
首先观察题目,FuncA不是虚函数,在子类中,将父类的FuncA隐藏起来了;FuncB是虚函数,且完成了重写;首先pa是A类型指针,指向子类,pa2也是A类型指针,指向父类;分别调用FuncA与FuncB时,pa调用FuncA函数时调用A类中的FuncA,调用FuncB时构成多态,调用子类的FuncB,接着pa2本身指向的就是父类,因此调用FuncA与FuncB时都是调用父类的;故选B;
10、在32位环境下,以上程序的输出结果是?
#include<iostream>
using namespace std;
class Base
{
public:
virtual int foo(int x)
{
return x * 10;
}
int foo(char x[14])
{
return sizeof(x) + 10;
}
};
class Derived: public Base
{
int foo(int x)
{
return x * 20;
}
virtual int foo(char x[10])
{
return sizeof(x) + 20;
}
} ;
int main()
{
Derived stDerived;
Base *pstBase = &stDerived;
char x[10];
printf("%d\n", pstBase->foo(100) + pstBase->foo(x));
return 0;
}
A. 2000
B. 2004
C. 2014
D. 2024正确答案:C
题解:
此题函数声明的与我们的第一题非常类似;父类与子类中的两个foo函数都各自分别构成重载,父类中int接口的foo函数定义成了虚函数,并在子类中完成了重写;接着我们来看主函数,定义了一个子类并用父类的指针指向该子类;printf函数中,我们第一个传入了一个整型,调用的子类int接口的foo函数,构成了多态;返回2000;第二个传入了字符数组,调用的是父类字符数组那个接口的foo函数,sizeof计算得到4+10,返回14(不知道为啥是4的可以看C语言指针强化);故选C;
四、编程题题解
1、完全数计算
思路:我们依次遍历1到n,记录完全数个数,没什么技巧;
#include <iostream>
using namespace std;
bool is_absolute(int num)
{
int sum = 0;
for(int i = 1; i < num; i++)
{
if(num % i == 0)
sum += i;
}
if(num == sum)
return true;
else
return false;
}
int main()
{
int n;
cin >> n;
int count = 0;
for(int i = 1; i <= n; i++)
{
if(is_absolute(i))
count++;
}
cout << count << endl;
return 0;
}
2、扑克牌大小
思路:本题主要考察string的使用,也没有什么算法,我们先判断是否存在王炸,如果存在直接返回;然后继续筛选,首先我们分别计算得到这两手牌的 第一个张牌、手牌数量;然后用string保存比较次序,然后如果手牌数量相同,直接比较第一张牌再次序表中的位置;如果手牌数量不相同,则看是否有一方有炸弹,如果有返回炸弹一方手牌,没有则返回ERROR;
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
string find_max(string& cards)
{
if(cards.find("joker JOKER") != string::npos)
return "joker JOKER";
// 分离两手牌
int pos = cards.find('-');
string play1 = cards.substr(0, pos);
string play2 = cards.substr(pos + 1);
// 统计两手牌个数
int card_num1 = count(play1.begin(), play1.end(), ' ') + 1;
int card_num2 = count(play2.begin(), play2.end(), ' ') + 1;
// 统计他两第一张牌
string card1 = play1.substr(0, play1.find(' '));
string card2 = play2.substr(0, play2.find(' '));
// 手牌比较依据数组
string str = "345678910JQKA2jokerJOKER";
if(card_num1 == card_num2)
{
if(str.find(card1) > str.find(card2))
return play1;
else
return play2;
}
else
{
if(card_num1 == 4)
return play1;
else if(card_num2 == 4)
return play2;
else
return "ERROR";
}
}
int main()
{
string cards;
getline(cin, cards);
cout << find_max(cards) << endl;
return 0;
}