
# 计算机二级 C++ 试题

**考试时间：120 分钟**  
**满分：100 分**

> **说明：**  
> 本试卷不涉及模板和智能指针，重点考查面向对象编程和简单算法的编程能力。

---

## 一、选择题 (共10题，每题2分，共20分)

1. 关于 C++ 的面向对象特性，下列描述正确的是：  D
   A. 封装使得数据与对数据的操作组合在一起  
   B. 继承支持代码复用  
   C. 多态允许同一操作在不同对象上表现出不同的行为  
   D. 以上全部

2. 在 C++ 中，class的默认访问权限是：  C
   A. public  
   B. protected  
   C. private  
   D. 无默认权限

3. 当类中存在虚函数时，运行时调用哪个函数版本取决于：  A
   A. 指针或引用所指对象的实际类型  
   B. 指针或引用的类型  
   C. 编译时绑定  
   D. 函数的参数列表

4. 如果希望禁止类对象的拷贝，通常的做法是：  C
   A. 不提供拷贝构造函数和赋值运算符  
   B. 将拷贝构造函数和赋值运算符声明为私有  
   C. 使用 const 修饰所有成员变量  
   D. 以上都不正确

5. 在 C++ 中，struct的默认访问权限是：  A
   A. public  
   B. protected  
   C. private  
   D. 无默认权限

6. 以下哪条语句正确包含了 iostream 头文件？  C
   A. `#import <iostream>`  
   B. `#include iostream`  
   C. `#include <iostream>`  
   D. `using namespace std;`  

7. 在 C++ 中，下列哪个运算符用于获取变量的地址？  A
   A. &  
   B. *  
   C. ->  
   D. %  

8. 以下哪一项是正确的函数声明？  B
   A. `int func(int a, b);`  
   B. `int func(int a, int b);`  
   C. `func(int a, int b);`  
   D. `int func(a, b);`  

9. 下列选项中，哪一个不是 C++ 的访问控制符？  D
   A. public  
   B. private  
   C. protected  
   D. external  

10. 关于 C++ 中的引用，以下说法正确的是：  A
      A. 引用必须在定义时初始化  
      B. 引用可以改变绑定的对象  
      C. 引用可以为 NULL  
      D. 引用占用额外的内存空间  

---

## 二、填空题 (共4题，每题2.5分，共10分)

1. C++ 的面向对象三大特性是封装、______继承__ 和多态。  
  
2. 成员函数在类外定义时需要使用 ______::__ 运算符指定其所属的类。  
  
3. 如果一个函数在基类中声明为虚函数，那么在派生类中重写该函数时可以选择在函数声明后加上 ______override__ 关键字以提高代码可读性。  
  
4. 递归算法必须包含一个或多个 ______终止__ 条件，以确保递归能够终止。  

---



---

## 三、代码分析题 (共2题，每题10分，共20分)


### 题目1

阅读下面的代码，并回答问题：

```cpp
#include <iostream>
using namespace std;

void modifyPointer(int *p) {
    *p = 20;
}

int main() {
    int a = 10;
    int *ptr = &a;
    
    modifyPointer(ptr);
    
    cout << a << endl;
    
    return 0;
}
```
1.程序的输出结果是什么？20
2.解释指针 ptr 在 modifyPointer 函数调用过程中的作用，以及它对变量 a 的影响。指向a的地址 修改a的值


### 题目2

阅读下面的代码，并回答问题：

```cpp
#include <iostream>
using namespace std;

class A {
public:
    A() {
        cout << "A Constructor" << endl;
    }
    ~A() {
        cout << "A Destructor" << endl;
    }
};

class B : public A {
public:
    B() {
        cout << "B Constructor" << endl;
    }
    ~B() {
        cout << "B Destructor" << endl;
    }
};

int main() {
    B obj;
    return 0;
}
```
1.程序的输出结果是什么？

A Constructor

B Constructor

B Destructor

A Destructor

2.解释下子类与父类的构造、析构函数的调用顺序。子类构造过了父类，子类析构过了父类

## 四、编程题 (共3题，共40分)

### 题目：基于继承与多态的学生管理系统设计 — 10分

**要求：**  
- 定义一个基类 `Person`，包含下列内容：
  - **保护成员**：姓名（`string`）
  - 构造函数：用于初始化姓名
  - **虚函数** `display()`：用于输出人员的基本信息
- 定义一个派生类 `Student`，继承自 `Person`，并添加下列私有成员：
  - 学号（`int`）
  - 成绩（`float`）
- 在 `Student` 类中，重写基类中的 `display()` 函数，输出学生的姓名、学号和成绩。
- 在 `main()` 函数中，创建至少两个 `Student` 对象，并使用基类 `Person` 类型的指针调用 `display()` 函数，体现虚函数的多态特性。
- 注意：请确保在基类中定义虚析构函数，以便正确释放派生类对象，请填充下面的代码实现。

**示例代码：**
```cpp
#include <iostream>
#include <string>
using namespace std;

// 基类 Person，包含姓名和虚函数 display()
class Person {
    protected:
        string name;
    public:

        Person(string n, int i, float g){
            name = n;
        }

        virtual void display(){

        }
};

// 派生类 Student，继承自 Person，并添加学号和成绩
class Student :public Person {
    private:
        int id;
        float grade;

    public:
        Student(string n,int i,float g) override{
            name =n;
            id = i;
            grade = g;
        }

        virtual void display() override{
            cout<<"学生的姓名："<<name<<endl;
            cout<<"学生的学号："<<id<<endl;
            cout<<"学生的成绩"<<grade<<endl;
        }


};

int main() {
    // 使用基类指针，体现多态性
    Person* p1 = new Student("张三", 1001, 88.5);
    Person* p2 = new Student("李四", 1002, 92.0);

    p1->display();
    p2->display();

    // 释放内存
    delete p1;
    delete p2;
    
    return 0;
}
```


---

### 题目2：递归实现二分查找  — 20分

**要求：**  
- 编写一个 C++ 程序，使用递归实现二分查找算法，在一个有序的整数数组中查找目标值。  
- 程序应要求用户输入一个目标值，若目标值存在，则输出其在数组中的下标；否则输出 -1。  
- 代码中应包含对输入数据的提示以及对边界条件的合理判断。

**示例代码：**
```cpp
#include <iostream>
using namespace std;

// 递归实现二分查找函数 请你填充此函数实现
int binarySearch(int arr[], int left, int right, int target) {
    while (left<=right){
        int mid = left + (right-left)/2;
        if(arr[mid]==target){
            return mid;
        }else if(arr[mid]<target){
            left = mid +1;
        }else{
            right = mid -1;
        }
    }
    return -1;
    
}

int main() {
    // 已排序的数组
    int arr[] = {1, 3, 5, 7, 9, 11, 13, 15};
    int n = sizeof(arr) / sizeof(arr[0]);
    
    int target;
    cout << "请输入要查找的目标值：";
    cin >> target;
    
    int index = binarySearch(arr, 0, n - 1, target);
    if(index != -1) {
        cout << "目标值 " << target << " 在数组中的下标为：" << index << endl;
    } else {
        cout << "目标值 " << target << " 不在数组中。" << endl;
    }
    return 0;
}
```

---

### 题目3：冒泡排序实现  — 10分

**要求：**  
- 编写一个 C++ 程序，定义一个整数数组，对数组进行冒泡排序。
- 程序应先输出排序前的数组，再输出排序后的数组。
- 代码要求体现出对冒泡排序核心思想的理解，结构清晰、注释明确，并注意边界情况的处理。

**示例代码：**
```cpp
#include <iostream>
using namespace std;

// 冒泡排序函数 请你填充这个函数
void bubbleSort(int arr[], int n) {
    for(int i=0;i<n-1;i++)
        for(int j=0;j<n-1-i;j++){
            if(arr[j]>arr[j+1]){
                swap(arr[j],arr[j+1]);
            }
        }
}

// 打印数组函数
void printArray(const int arr[], int n) {
    for (int i = 0; i < n; i++) {
        cout << arr[i] << " ";
    }
    cout << endl;
}

int main() {
    int arr[] = { 5, 3, 8, 6, 2, 7, 4, 1 };
    int n = sizeof(arr) / sizeof(arr[0]);
    
    cout << "排序前的数组：" << endl;
    printArray(arr, n);
    
    bubbleSort(arr, n);
    
    cout << "排序后的数组：" << endl;
    printArray(arr, n);
    
    return 0;
}
```


**注意事项：**  
- 请仔细阅读每道题目的要求，确保在答题时详细阐述思路及关键实现步骤。  
- 编程题请在本地编译测试确保代码正确无误。  

祝各位考生考试顺利！