大一下 校软C++ 考核试题

Tips:

  1. 本试卷所有题目基于 C++11 标准环境
  2. Windows 下数据模型采用 LLP64 模型, Unix-like 下则采用 LP64 模型
  3. Windows 下编译器环境为 TDM-GCC 4.9.2 (dev-C++ 5.11), Unix-like 下编译器环境为 gcc 8.2.1
  4. 所有题目允许使用STL

单项选择题

  1. C++程序设计语言诞生于 ( C )
    A. 美国国家标准学会 B. 国际标准组织
    C. 贝尔实验室 D. 麻省理工学院

    • 浅谈C++ 起源

      为支持面向对象的程序设计,1980年由贝尔实验室的Bjarne Stroustrup创建了C++程序设计语言。

  2. C++中类与结构体的主要区别在于 ( D )
    A. 声明时的关键字不同 B. 默认成员访问模式不同
    C. 是否含有静态成员 D. 是否具有类属性的关键字或内容

    • A struct class 都可以定义 类

      C/C++ struct & class 区别

      C/C++ class-key

      struct 和class 都可以定义 C++ 中的 类,当且仅当 由struct定义的结构体中

      含有 class 特有的属性时,struct 相当于 class (比如 构造函数和析构函数)

    • B 默认class 默认 private struct 默认 public,但是不主要区别

    • C 都可以写 static ,是共同点

    • D 显然 class 和 struct 的类属性具有许多的不同点

      • 类属性

        1. 数据成员

        a) 非静态数据成员,包括位域

        b) 静态数据成员

        1. 成员函数

        a) 非静态成员函数

        b) 静态成员函数

        1. 嵌套类型

        a) 定义于类定义中的嵌套类枚举

        b) 既存类型的别名,以 typedef类型别名声明定义

        c) 在类自身定义中的类名称表现为其自身的 public 成员类型别名,为了查找之便(除非在用作构造函数名时):这被称作注入类名

        1. 定义于类中的所有无作用域枚举的枚举项

        2. 成员模板(变量模板、 (C++14 起)类模板或函数模板)可出现于任何非局部 class/struct/union 定义体内。

  3. 现有二维数组 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

    • strlen() 与 sizeof() 区别

      (1) sizeof是一个C语言中的一个单目运算符,而strlen是一个函数,用来计算字符串的长度。

      (2) sizeof求的是数据类型所占空间的大小,而strlen是求字符串的长度

  4. C++对于多继承出现 菱形继承(钻石继承) 的解决方案是 ( C )
    A. C3线性化 B. 接口
    C. 多态 D. 禁止

  5. 下列哪一项不是引用和指针的三大区别之一 ( A )
    A. 任何类型的引用占用内存大小都相同, 但指针不同
    B. 不存在空引用, 但存在空指针
    C. 引用需要初始化, 但指针不需要
    D. 引用永远指向被引用的对象, 但指针可以指向其他同类型对象

    • 由第3题,我们得知 在同种环境的任何情况下指针都是 8 位 或 4 位

      而 引用 只是别名 ,不占内存空间 ,sizeof() 会对 被引用 的类型进行计算

      C++ 引用和指针的区别

  6. 以下不可以重载的运算符有 ( D )
    A. 数组下标 ([]) B. 指针的成员 (->)
    C. 取地址 (&) D. 对象的成员 (.)

  7. 动态联编发生在程序的以下哪个阶段 ( B )
    A. 编译期 B. 运行期 C. 预处理期 D. 写代码期

    动态联编与静态联编

  8. 一个函数功能不太复杂, 但要求被频繁调用, 则应该将这个函数定义为 ( A )
    A. 内联函数 B. 递归函数
    C. 嵌套函数 D. 重载函数

判断题

  1. 类无法保证成员在内存中的顺序, 但结构体可以。 ( √ )

  2. "多态类型" 可以理解为是带有虚函数的类类型, "多态对象" 可以理解为是一个不止一种类型的对象。 ( √ )

    • 对象的多态由 虚函数实现
  3. 析构函数在对象生命周期结束时自动调用, 无法用户手动调用。 ( × )

    • 可以直接delete 对象
  4. 在 Lambda表达式 中, 可以使用 auto 自动推导形参类型。 ( × )

  5. 在类中特殊成员函数包含构造函数、复制构造函数、复制赋值运算符和析构函数。 ( √ )

    C++ 特殊成员函数

  6. 假设先有类C, 则该类的构造函数 C() = delete; 的含义为 显式强制编译器自动生成默认构造函数 。 ( ×)

    C++ delete 与 default 的区别

  7. sizeof 是一种运算符, 作用域解析符(::) 也是一种运算符。 ( × )

    :: 不是运算符

    C++ 运算符

填空题

  1. 有一结构体如下, 它所占用的内存大小 为 ( 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

  2. 在以下代码的输出结果为 ( 1 )

    class C {};
    std::cout << sizeof(C);
    

    C++中空类的大小为1的原因

  3. 补全以下代码, 使输出为 "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 关键字的作用

    在虚函数声明或定义中使用时, final 确保函数为虚且不可被派生类覆写。

    explicit 关键字详解

    C++ 虚函数详解

    C++多态--虚函数virtual及override

    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++ 自动调用析构的
    
    //  构造和析构的顺序就像一个  栈  (数据结构) , 先构造的后析构,后构造的先析构
    
  4. 给定区间 [-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";
    

简答题

​ (一下两道主观题,笔者只给出参考,每个人的答案都是不近相同的)

  1. 请简述 重载 (overload)重写 (Override) 的区别

    重写可以有两种,直接重写成员函数和重写虚函数,只有重写了虚函数的才能算作是体现了C++多态性。

    重载则是允许有多个同名的函数,而这些函数的参数列表不同,允许参数个数不同,参数类型不同,或者两者都不同。编译器会根据这些函数的不同列表,将同名的函数的名称做修饰,从而生成一些不同名称的预处理函数,来实现同名函数调用时的重载问题。但这并没有体现多态性。

  2. 请简述, 你眼中的C/C++有什么异同

    C 与 C++ 的区别

附在最后

原文地址:https://www.cnblogs.com/lukelmouse/p/10719605.html