一. 单选
1. 假设A为抽象类,下列声明()是正确的
A int fun(A);
B A Obj;
C A fun(int);
D A *p;
正确答案:D
抽象类不能实例化对象
2. 虚函数可不可以重载为内联?
A 可以
B 不可以
C 语法错误
正确答案:B
虚函数需要函数地址,内联函数直接将该函数展开,不存在地址
3. 下面有关虚函数的描述,说法错误的是?
A 虚函数的作用是实现了继承性
B 虚函数的作用就是实现“动态联编”,也就是在程序的运行阶段动态地选择合适的成员函数
C 和类的静态成员函数与非类的成员函数相比,虚函数的效率较低
D 要正确的实现虚函数,只能用一个基类的指针或者引用来指向派生类对象
正确答案:A
继承是为了实现多态,多态需要虚函数
4.下面这个代码输出的是()
#include <iostream>
#include <vector>
using namespace std;
int main(void) {
vector<int>array;
array.push_back(100);
array.push_back(300);
array.push_back(300);
array.push_back(300);
array.push_back(300);
array.push_back(500);
vector<int>::iterator itor;
for (itor = array.begin(); itor != array.end(); itor++) {
if (*itor == 300) {
itor = array.erase(itor);
}
}
for (itor = array.begin(); itor != array.end(); itor++) {
cout << *itor << "";
}
return 0;
}
A 100 300 300 300 300 500
B 100 300 300 300 500
C 100 300 300 500
D 100 300
正确答案:C
5. 在 C++ 中,用于实现动态多态性的是( )。
A 内联函数
B 重载函数
C 模板函数
D 虚函数
正确答案:D
6. 调用一成员函数时, 使用动态联编的情况是()
A 通过对象调用一虚函数
B 通过指针或引用调用一虚函数
C 通过对象调用静态函数
D 通过指针或应用调用一静态函数
正确答案:B
7. 下面有关继承、多态、组合的描述,说法错误的是?
A 封装,把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏
B 继承可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展
C 隐藏是指派生类中的函数把基类中相同名字的函数屏蔽掉了
D 覆盖是指不同的函数使用相同的函数名,但是函数的参数个数或类型不同
正确答案:D
覆盖是指不同的函数使用相同的虚函数名,函数的参数个数和类型相同
8. “引用”与多态的关系?
A 两者没有关系
B 引用可以作为产生多态效果的手段
C 一个基类的引用不可以指向它的派生类实例
D 以上都不正确
正确答案:B
9. 下面这段程序的输出是什么?
class A {
public:
A() {
p();
}
virtual void p() {
printf("A");
}
virtual ~A() {
p();
}
};
class B: public A {
public:
B() {
p();
}
void p() {
printf("B");
}
~B() {
p();
}
};
int main(int, char**) {
A* a = new B();
delete a;
}
A AABB
B BBAA
C ABAB
D ABBA
正确答案:D
B继承了A
A* a = new B();
先构造父类(A),再构造子类(B)
delete a;析构函数虚函数重写了,所以调用子类(B)的析构函数
先构造的后析构,所以先析构B,再析构A
10. 以下代码的运行结果为()
class Base {
public:
Base() {
echo();
}
virtual void echo() {
printf("Base");
}
};
class Derived: public Base {
public:
Derived() {
echo();
}
virtual void echo() {
printf("Derived");
}
};
int main() {
Base* base = new Derived();
base->echo();
return 0;
}
A DerivedDerivedDerived
B DerivedBaseDerived
C BaseDerivedBase
D BaseDerivedDerived
正确答案:D
Base* base = new Derived();
先构造父类再构造子类 "BaseDerived"
base->echo();echo()实现虚函数的重写,并且父类的指针指向子类的对象,所以构成多态,调用子类echo()函数 "Derived"
二、编程
题目ID:36877-杨辉三角的变形
链接:https://www.nowcoder.com/practice/8ef655edf42d4e08b44be4d777edbf43?tpId=37&&tqId=21276&rp=1&ru=/activity/oj&qru=/ta/huawei/question-ranking
【解题思路】:
通过以上的数据分析规律为 {-1,-1,2,3,2,4,2,3,2,4,...} ,即第n行上偶数所在的下标
#include<iostream>
#include<string>
using namespace std;
int main(int argc, char* argv[]) {
int nRow = 0;
while (cin >> nRow) {
int res = -1;
int myInt[] = {4, 2, 3, 2};
if (nRow > 2)
res = myInt[(nRow - 2) % 4];
cout << res << endl;
}
return 0;
}
题号:36826 计算某字符出现次数
【链接】
https://www.nowcoder.com/questionTerminal/a35ce98431874e3a820dbe4b2d0508b1
【题目描述】
写出一个程序,接受一个由字母、数字和空格组成的字符串,和一个字符,然后输出输入字符串中该字符的出现次数。(不区分大小写字母)
数据范围: 1 ≤ n ≤ 1000
【题目解析】
首先,字符串中包含有空格,因此我们使用 gets 函数获取一行数据,而不用 scanf ,因为 scanf 函数会默认以空格截断输入作为输入的结束.
其次,因为在计算字符出现次数中,要求是不区分大小写的,因此在处理过程中,如果输入的是小写字母,则计数不但要加上小写字母的计数,还要加上大写字母的计数,反之大写字母也是同样如此,而在 ascii 表中,大写字母和小写字母的差值是 32 ( 'a'的ascii值是97 ; 'A'的ascii值是65 )
最后,实现思路,因为 ascii字符 只有 128 个,他们的实际存储是 0~127 ,那么我们只需要定义一个具有
128 个整形元素的数组,第 0 号下标位置存放 0 对应的 ascii字符 出现次数, 1 号下标位置存放 1 对应
的 ascii字符 的次数....以此类推,数组每个位置存放的就是对应 ascii字符 出现的次数。最终以指定字符为下标获取它出现的次数进行打印。
#include <stdio.h>
#include <string.h>
int main() {
char str[1003] = { 0 };
//gets函数获取一行数据,因为会连带最后的换行一起获取,所以不用担心遗留的换行对后续输入造成影响gets(str);
char find;
scanf("%c", &find);//捕捉要查找的字符
int count[128] = { 0 };//用于记录每个字符出现次数
int len = strlen(str);//获取字符串实际长度
for (int i = 0; i < len; i++) {
count[str[i]] += 1; //对应字符的位置计数+1
}
int res = count[find];
if (find >= 'A' && find <= 'Z') {//如果是A-Z需要将a-z对应的计数加上
res += count[find + 32];
} else if (find >= 'a' &&
find <= 'z') { //如果是a-z需要将A-Z对应的计数加上
res += count[find - 32];
}
printf("%d\n", res);
return 0;
}