一. 单选
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));
}
A 100,-100
B 100,50
C 200,-100
D 200,50
正确答案:B
2. 关于函数的描述正确的是()
A 虚函数是一个static型的函数
B 派生类的虚函数与基类的虚函数具有不同的参数个数和类型
C 虚函数是一个非成员函数
D 基类中说明了虚函数后,派生类中起对应的函数可以不必说明为虚函数
正确答案:D
A:静态函数没有this指针,不能是虚函数
B:虚函数重写三同:函数名相同、返回值相同、参数的类型和个数相同
C:虚函数必须是成员函数,才能形成虚表
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
4. 当一个类的某个函数被说明为virtual,则在该类的所有派生类中的同原型函数_____?
A 只有 被重新说明时才识虚函数
B 只有被重新说明为virtual时才是虚函数
C 都不是虚函数
D 都是虚函数
正确答案:D
5. 下面有关虚函数和非虚函数的区别说法错误的是?
A 子类的指针访问虚函数访问的是子类的方法
B 子类的指针访问非虚函数访问的是子类的方法
C 父类的指针访问虚函数访问的是父类的方法
D 父类的指针访问非虚函数访问的是父类的方法
正确答案: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();
}
A A:print()
B B:print()
C 编译出错
正确答案:C
B私有继承A,A的所有成员在B里面都是私有
C继承B,父类(B)的私有成员子类(C)无法访问
7. 以下关于C++的描述中哪一个是正确的()
A 任何指针都必须指向一个实例
B 子类指针不可以指向父类实例
C 任何引用都必须指向一个实例
D 引用所指向的实例不可能无效
正确答案:C
A:指针可以指向NULL
B:一般不行,但可以强转
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;
}
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
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
二、 编程
题目ID:36880-完全数计算
链接:https://www.nowcoder.com/practice/7299c12e6abb437c87ad3e712383ff84tpId=37&&tqId=21279&rp=1&ru=/activity/oj&qru=/ta/huawei/question-ranking
【解题思路】:
本题可以通过遍历每一个约数,求和,判断完全数。约数计算可以遍历sqrt(n)的范围。
#include<iostream>
using namespace std;
int Count_Of_Perfect_Number(int n) {
int count = 0, sum = 0;
for (int i = 2; i <= n; ++i) {
for (int j = 1; j < i; ++j) { //效率不高
if (i % j == 0) //对约数进行求和
sum += j;
}
if (sum == i)
count++;
sum = 0;
}
return count;
}
int main() {
int n, count;
while (cin >> n) {
count = Count_Of_Perfect_Number(n);
cout << count << endl;
}
return 0;
}
题目ID:36912-扑克牌大小
链接:https://www.nowcoder.com/practice/0a92c75f5d6b4db28fcfa3e65e5c9b3f?tpId=49&&tqId=29277&rp=1&ru=/activity/oj&qru=/ta/2016test/question-ranking
【题目解析】:
本题的题目意思是输入的只是这些类型中的一种,个子,对子,顺子(连续5张),三个,炸弹(四个)和对王。其实就是最多5张牌(顺子),最少1一张牌之间的比较。不存在其他情况。
【解题思路】:
由输入保证两手牌都是合法的,顺子已经从小到大排列,按照题意牌面类型的确定和大小的比较直接可以转换为牌个数的比较。
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
string FindMax(const string& line) {
if (line.find("joker JOKER") != string::npos)
return "joker JOKER";
int dash = line.find('-');
//分开两手牌
string car1 = line.substr(0, dash);
string car2 = line.substr(dash + 1);
//获取两手牌的张数
int car1_cnt = count(car1.begin(), car1.end(), ' ') + 1;
int car2_cnt = count(car2.begin(), car2.end(), ' ') + 1;
//获取两手牌的各自第一张牌
string car1_first = car1.substr(0, car1.find(' '));
string car2_first = car2.substr(0, car2.find(' '));
if (car1_cnt == car2_cnt) { //两手牌的类型相同
string str = "345678910JQKA2jokerJOKER";
if (str.find(car1_first) > str.find(car2_first))
return car1;
return car2;
}
if (car1_cnt == 4) //说明是炸弹
return car1;
else if (car2_cnt == 4)
return car2;
return "ERROR";
}
int main() {
string line, res;
while (getline(cin, line)) {
res = FindMax(line);
cout << res << endl;
}
return 0;
}