大一下 校软C++ 考核试题
Tips:
- 本试卷所有题目基于 C++11 标准环境
- Windows 下数据模型采用 LLP64 模型, Unix-like 下则采用 LP64 模型
- Windows 下编译器环境为 TDM-GCC 4.9.2 (dev-C++ 5.11), Unix-like 下编译器环境为 gcc 8.2.1
- 所有题目允许使用STL
单项选择题
-
C++程序设计语言诞生于 ( C )
A. 美国国家标准学会 B. 国际标准组织
C. 贝尔实验室 D. 麻省理工学院-
为支持面向对象的程序设计,1980年由贝尔实验室的Bjarne Stroustrup创建了C++程序设计语言。
-
-
C++中类与结构体的主要区别在于 ( D )
A. 声明时的关键字不同 B. 默认成员访问模式不同
C. 是否含有静态成员 D. 是否具有类属性的关键字或内容-
A struct class 都可以定义 类
struct 和class 都可以定义 C++ 中的 类,当且仅当 由struct定义的结构体中
含有 class 特有的属性时,struct 相当于 class (比如 构造函数和析构函数)
-
B 默认class 默认 private struct 默认 public,但是不主要区别
-
C 都可以写 static ,是共同点
-
D 显然 class 和 struct 的类属性具有许多的不同点
-
-
现有二维数组
char *arr[5] = {"1234567890", "qwerty", "asdfghjkl", "zxcvbnm", "[,.]"};
, 则 sizeof(arr) 和 strlen(arr[2]) 的值分别为 ( A )
A. 40, 9 B. 36, 9
C. 41, 10 D. 41, 9- *arr是一个指针数组,里面包含有五个指针 分别 指向 “1234567890”。。。
sizeof(arr)代表的是 指针数组的大小,而不是 指针所指的对象的大小,
因此 答案: 5 * 8,(在LLP64 和 LP64 下) 不管是什么指针,大小都为8byte
(其他情况下 指针的大小有可能为 4 ,但是这套题规定了环境,所以指针大小为 8)
-
strlen(arr[2]) == strlen("asdfghjkl") == 9
-
(1) sizeof是一个C语言中的一个单目运算符,而strlen是一个函数,用来计算字符串的长度。
(2) sizeof求的是数据类型所占空间的大小,而strlen是求字符串的长度
-
C++对于多继承出现
菱形继承(钻石继承)
的解决方案是 ( C )
A. C3线性化 B. 接口
C. 多态 D. 禁止 -
下列哪一项不是引用和指针的三大区别之一 ( A )
A. 任何类型的引用占用内存大小都相同, 但指针不同
B. 不存在空引用, 但存在空指针
C. 引用需要初始化, 但指针不需要
D. 引用永远指向被引用的对象, 但指针可以指向其他同类型对象-
由第3题,我们得知 在同种环境的任何情况下指针都是 8 位 或 4 位
而 引用 只是别名 ,不占内存空间 ,sizeof() 会对 被引用 的类型进行计算
-
-
以下不可以重载的运算符有 ( D )
A. 数组下标 ([]) B. 指针的成员 (->)
C. 取地址 (&) D. 对象的成员 (.) -
动态联编发生在程序的以下哪个阶段 ( B )
A. 编译期 B. 运行期 C. 预处理期 D. 写代码期 -
一个函数功能不太复杂, 但要求被频繁调用, 则应该将这个函数定义为 ( A )
A. 内联函数 B. 递归函数
C. 嵌套函数 D. 重载函数
判断题
-
类无法保证成员在内存中的顺序, 但结构体可以。 ( √ )
-
特指 C 中的结构体
-
-
"多态类型" 可以理解为是带有虚函数的类类型, "多态对象" 可以理解为是一个不止一种类型的对象。 ( √ )
- 对象的多态由 虚函数实现
-
析构函数在对象生命周期结束时自动调用, 无法用户手动调用。 ( × )
- 可以直接delete 对象
-
在 Lambda表达式 中, 可以使用 auto 自动推导形参类型。 ( × )
-
该试卷规定了C++ 11 (不可以),但是 C++ 14 可以
-
-
在类中特殊成员函数包含构造函数、复制构造函数、复制赋值运算符和析构函数。 ( √ )
-
假设先有类C, 则该类的构造函数
C() = delete;
的含义为 显式强制编译器自动生成默认构造函数 。 ( ×) -
sizeof
是一种运算符,作用域解析符(::)
也是一种运算符。 ( × ):: 不是运算符
填空题
-
有一结构体如下, 它所占用的内存大小 为 ( 48 ) (单位: 字节)
struct Struct { short a; // 2 int b; //4 unsigned char c; // 1 long long d; // 8 char e; // 1 short f, g; // 2 , 2 int h; // 4 int (*func)(int); // 8 };
-
内存对齐 (x),代表 补x位
前三个short + int + unsigned int == 2 + (2) + 4 + 1 + (7) == 16
long long 为 8,char 为 1 + (7) == 8
short 为 2 + 2 + (4) == 8
int 4 + (4) == 8
指针一律为 8
16 + 4 * 8 == 48
-
-
在以下代码的输出结果为 ( 1 )
class C {}; std::cout << sizeof(C);
-
补全以下代码, 使输出为 "Class BaseClass Virtual BaseFunc Final1Final2".
class Base { public: explicit Base() { cout << "Class Base"; } virtual void func() { cout << " BaseFunc "; } virtual ~Base() { (1) } }; class Virtual : public Base { public: explicit Virtual() : Base() { cout << "Class Virtual"; } virtual void func() final { cout << " VirtualFunc "; } virtual ~Virtual() { (2) } }; Virtual* p_virtual = new Virtual(); (3)
(1) cout<<"Final2"; (2) cout<<"Final1"; (3) p_virtual->Base::func(); delete p_virtual;
在虚函数声明或定义中使用时,
final
确保函数为虚且不可被派生类覆写。Virtual* p_virtual = new Virtual();//(创建一个Virtual类的对象指针,并初始化一个Virtual 对象) /* new Virtual() 时, 会自动调用 基类的构造函数 然后 再调用子类的构造函数 输出 Class BaseClass Virtual, 要输出基类 Base 的 func ,需要 这么调用 p_virtual->Base::func() ,Base::用来指定调用哪 一个类的func,(因为基类 和 子类 都有一个 func) 否则 , 如果这么写的话 p_virtual->func(); ,会调用 子类的func, 输出 VirtualFunc(虚函数的作用) */ delete p_virtual;// 如果不手动 delete ,就不能调用析构函数,系统不会为C++ 自动调用析构的 // 构造和析构的顺序就像一个 栈 (数据结构) , 先构造的后析构,后构造的先析构
-
给定区间 [-231, 231] 内的3个整数A、B和C, 填写代码完成判断A+B是否大于C, 若大于输出 true 反之输出 false
#include <iostream> using namespace std; int main() { int n; scanf("%d", &n); for (int i = 0; i < n; i++) { (1) cin >> a >> b >> c; printf((2)); } return 0; }
(4) long long a,b,c; // 输入数据在int范围呢,但是 int_max + int_max 会溢出,所以用long long (5) a + b > c ? "true" : "false";
简答题
(一下两道主观题,笔者只给出参考,每个人的答案都是不近相同的)
-
请简述 重载 (overload) 和 重写 (Override) 的区别
重写可以有两种,直接重写成员函数和重写虚函数,只有重写了虚函数的才能算作是体现了C++多态性。
重载则是允许有多个同名的函数,而这些函数的参数列表不同,允许参数个数不同,参数类型不同,或者两者都不同。编译器会根据这些函数的不同列表,将同名的函数的名称做修饰,从而生成一些不同名称的预处理函数,来实现同名函数调用时的重载问题。但这并没有体现多态性。
-
请简述, 你眼中的C/C++有什么异同