【C++初中高中组选择题】

  1. 指针声明正确的是:
    A. int p = &a;
    B. int* p = a;
    C. int* p = &a;
    D. int p* = &a;

  2. 动态分配的数组应如何释放?
    A. delete arr;
    B. delete arr[];
    C. delete[] arr;
    D. delete (arr);

  3. 函数重载的必要条件是:
    A. 返回值类型不同
    B. 参数列表不同
    C. 函数名不同
    D. 作用域不同

  4. 递归函数必须包含:
    A. 循环语句
    B. 静态变量
    C. 终止条件
    D. 全局变量

  5. 读取文件应使用哪个类?
    A. ofstream
    B. ifstream
    C. fstream
    D. iostream

  6. 结构体变量初始化正确的是:
    A. Student s = "Tom", 90;
    B. Student s = {"Tom", 90};
    C. Student s = (name: "Tom", score: 90);
    D. Student s = new Student{"Tom", 90};

  7. 链表节点 Node{2, nullptr}next 指针指向:
    A. 自身
    B. 空地址
    C. 下一个节点
    D. 头节点

  8. 二维数组 matrix[3][3] 中,matrix[1][2] 的值是:
    A. 5
    B. 6
    C. 8
    D. 9

  9. s.substr(0,5) 的作用是:
    A. 删除前5个字符
    B. 截取前5个字符
    C. 替换前5个字符
    D. 反转前5个字符

  10. 质数判断优化时,循环条件应为:
    A. i < n
    B. i <= sqrt(n)
    C. i*i <= n
    D. i <= n/2

  11. 埃拉托斯特尼筛法用于:
    A. 计算质因数
    B. 筛选质数
    C. 求最大公约数
    D. 分解整数

  12. 辗转相除法求GCD(12,18)的结果是:
    A. 3
    B. 6
    C. 12
    D. 18

  13. 快速幂算法的时间复杂度是:
    A. O(n)
    B. O(log n)
    C. O(n²)
    D. O(1)

  14. 分解质因数时,循环变量 i 的起始值是:
    A. 0
    B. 1
    C. 2
    D. 任意数

  15. 数字反转函数 reverse(123) 的返回值是:
    A. 123
    B. 321
    C. 213
    D. 312

  16. 二分查找的前提条件是:
    A. 数组无序
    B. 数组有序
    C. 数组元素唯一
    D. 数组长度为奇数

  17. 贪心算法解决硬币找零问题时:
    A. 总是选择面值最小的硬币
    B. 总是选择面值最大的硬币
    C. 随机选择硬币
    D. 需要回溯

  18. 递归计算 factorial(5) 的结果是:
    A. 5
    B. 24
    C. 120
    D. 720

  19. 快速幂算法中,b 的更新操作是:
    A. b *= 2
    B. b /= 2
    C. b -= 1
    D. b += 1

  20. money=27,贪心算法找零需要的硬币数是:
    A. 5(102 + 51 + 1*2)
    B. 3(10+10+5+2)
    C. 4(10+5+5+5+2)
    D. 5(5+5+5+5+7)

【阅读程序题】

一、题目描述 阅读以下 C++ 代码,该代码实现了一些数论相关的功能以及使用了动态内存分配和函数重载。请根据代码回答后面的问题。


#include <iostream>
#include <cmath>

bool isPrime(int n) {
    if (n <= 1) return false;
    for (int i = 2; i < n; i++) {
        if (n % i == 0) return false;
    }
    return true;
}

bool isPrime(double num) {
    int n = static_cast<int>(num);
    if (n <= 1) return false;
    for (int i = 2; i <= std::sqrt(n); i++) {
        if (n % i == 0) return false;
    }
    return true;
}

// 动态分配数组并填充质数
int* generatePrimes(int size) {
    int* primes = new int[size];
    int count = 0;
    int num = 2;
    while (count < size) {
        if (isPrime(num)) {
            primes[count++] = num;
        }
        num++;
    }
    return primes;
}

int main() {
    int size = 10;
    int* primeArray = generatePrimes(size);

    std::cout << "前 " << size << " 个质数为: ";
    for (int i = 0; i < size; i++) {
        std::cout << primeArray[i] << " ";
    }
    std::cout << std::endl;

    // 检查一个浮点数是否为质数
    double testNum = 17.0;
    if (isPrime(testNum)) {
        std::cout << testNum << " 被认为是质数。" << std::endl;
    } else {
        std::cout << testNum << " 不被认为是质数。" << std::endl;
    }

    delete[] primeArray;
    return 0;
}
  1. 代码中定义了两个 isPrime 函数,这体现了 C++ 的什么特性?( ) A. 函数递归 B. 函数重载 C. 动态内存分配 D. 模板函数

  2. isPrime(double num) 函数中,static_cast<int>(num) 的作用是什么?( ) A. 将浮点数 num 转换为整数,用于后续质数判断 B. 将整数 num 转换为浮点数 C. 只是一个占位操作,无实际作用 D. 用于检查 num 是否为整数

  3. generatePrimes 函数中,while (count < size) 循环的作用是什么?( ) A. 计算小于 size 的所有数 B. 找到 size 个质数并填充到动态分配的数组中 C. 检查 size 是否为质数 D. 动态分配 size 大小的数组

  4. 假设 size 的值为 5,generatePrimes 函数返回的数组中存储的质数是哪些?( ) A. 2, 3, 5, 7, 9 B. 2, 3, 5, 7, 11 C. 1, 2, 3, 5, 7 D. 2, 4, 6, 8, 10

  5. main 函数中,delete[] primeArray; 这行代码的作用是什么?( ) A. 删除 primeArray 指针 B. 释放 primeArray 所指向的动态分配的内存,避免内存泄漏 C. 将 primeArray 所指向的数组元素全部设为 0 D. 只是一个语法习惯,无实际作用

  6. 关于代码中对浮点数 testNum 的质数判断,以下说法正确的是?( ) A. 由于浮点数精度问题,这种判断可能不准确 B. 先将浮点数转换为整数再判断,所以结果准确 C. 浮点数不能进行质数判断,代码会报错 D. 直接对浮点数进行质数判断,结果不可靠

二、题目描述:

阅读以下代码段,回答第1~6题:

#include <iostream>
using namespace std;
// 代码段A
bool isPrime(int n) {
    if (n <= 1) return false;
    for (int i = 2; i * i <= n; i++) {
        if (n % i == 0) return false;
    }
    return true;
}

// 代码段B
struct Node {
    int data;
    Node* next;
};

void insertFront(Node* head, int val) {
    Node* newNode = new Node{val, head->next};
    head->next = newNode;
}

// 代码段C
int mystery(int n) {
    if (n == 0) return 1;
    return n * mystery(n - 1);
}

// 代码段D
int fastPow(int a, int b) {
    int res = 1;
    while (b > 0) {
        if (b % 2 == 1) res *= a;
        a *= a;
        b /= 2;
    }
    return res;
}

int main() {
    // 测试A
    cout << "Is 17 prime? " << boolalpha << isPrime(17) << endl;

    // 测试B
    Node* head = new Node{0, nullptr};
    insertFront(head, 1);
    insertFront(head, 2);
    insertFront(head, 3);
    
    cout << "Linked list: ";
    Node* current = head->next;
    while (current != nullptr) {
        cout << current->data << " ";
        current = current->next;
    }
    cout << endl;

    // 测试C
    cout << "5! = " << mystery(5) << endl;

    // 测试D
    cout << "2^10 = " << fastPow(2, 10) << endl;

    // 释放链表内存
    while (head != nullptr) {
        Node* temp = head;
        head = head->next;
        delete temp;
    }

    return 0;
}

  1. 代码段A中,当输入n=25时,循环执行次数是
    A) 3次
    B) 4次
    C) 5次
    D) 6次

  2. 代码段B的insertFront函数执行后,链表会发生什么变化?
    A) 在头节点前插入新节点
    B) 在头节点后插入新节点
    C) 替换头节点的数据
    D) 链表变为环形结构

  3. 调用mystery(4)的返回值是
    A) 4
    B) 12
    C) 24
    D) 48

  4. 代码段D中,fastPow(2, 5)的计算结果是
    A) 16
    B) 25
    C) 32
    D) 64

  5. 若删除代码段A中的i * i <= n,改为i <= n,会导致
    A) 正确判断所有质数
    B) 将合数误判为质数
    C) 栈溢出错误
    D) 时间复杂度从O(√n)变为O(n)

  6. 在代码段B的基础上,若连续执行:
    insertFront(head, 5); insertFront(head, 7); 最终链表的顺序是
    A) 5 → 7
    B) 7 → 5
    C) 头节点 → 5 → 7
    D) 头节点 → 7 → 5

三、题目描述 假设你有一个文本文件 numbers.txt,文件中每行存储一个整数。现在要求编写一个 C++ 程序,通过分治递归的方法,计算文件中所有整数的总和,并将结果输出到另一个文件 result.txt 中。

参考代码

#include <iostream>
#include <fstream>
#include <vector>

void readNumbersFromFile(const std::string& filename, std::vector<int>& numbers) {
    std::ifstream file(filename);
    if (file.is_open()) {
        int num;
        while (file >> num) {
            numbers.push_back(num);
        }
        file.close();
    } else {
        std::cerr << "无法打开文件: " << filename << std::endl;
    }
}

int divideAndConquerSum(const std::vector<int>& numbers, int left, int right) {
    if (left > right) {
        return 0;
    }
    if (left == right) {
        return numbers[left];
    }
    int mid = (left + right) / 2;
    int leftSum = divideAndConquerSum(numbers, left, mid);
    int rightSum = divideAndConquerSum(numbers, mid + 1, right);
    return leftSum + rightSum;
}

int main() {
    std::vector<int> numbers;
    readNumbersFromFile("numbers.txt", numbers);

    int totalSum = divideAndConquerSum(numbers, 0, numbers.size() - 1);

    std::ofstream outFile("result.txt");
    if (outFile.is_open()) {
        outFile << "文件中所有整数的总和为: " << totalSum << std::endl;
        outFile.close();
    } else {
        std::cerr << "无法打开文件: result.txt" << std::endl;
    }

    return 0;
}
  1. readNumbersFromFile 函数中,while (file >> num) 的作用是什么?( ) A. 从文件中读取一个字符 B. 从文件中读取一行字符串 C. 从文件中读取一个整数,并存储到 num 中 D. 检查文件是否读取到末尾

  2. divideAndConquerSum 函数体现了分治递归的思想,其中 int mid = (left + right) / 2; 这行代码的作用是?( ) A. 计算数组的中间位置,用于将数组分成两部分 B. 计算数组元素的平均值 C. 作为递归的终止条件 D. 用于判断数组是否为空

  3. 如果 numbers.txt 文件中的内容为 1 2 3 4 5,那么 divideAndConquerSum 函数递归调用的次数是多少?( ) A. 4 B. 5 C. 8 D. 9

  4. main 函数中,如果 readNumbersFromFile 函数无法打开 numbers.txt 文件,程序会如何处理?( ) A. 程序会继续执行,totalSum 会被赋值为 0 B. 程序会输出错误信息并终止 C. 程序会尝试创建一个新的 numbers.txt 文件 D. 程序会忽略该错误,继续执行后续代码

  5. 关于 divideAndConquerSum 函数的递归终止条件,以下说法正确的是?( ) A. 当 left > right 时,说明数组为空,返回 0 B. 当 left == right 时,说明只有一个元素,返回该元素值 C. 当 mid 为 0 时,返回 0 D. A 和 B 都正确

  6. 如果要在程序中添加功能,统计文件中奇数的个数,并将结果也输出到 result.txt 文件中,以下代码应插入到程序的哪个位置最合适?( ) A. 在 readNumbersFromFile 函数中读取数字后统计 B. 在 divideAndConquerSum 函数中递归过程中统计 C. 在 main 函数中计算出 totalSum 之后统计 D. 在 main 函数中打开 result.txt 文件之后统计

【完善程序题】

密码强度评估程序 一般来说,质数在密码学中有重要应用,因为基于质数的运算往往具有单向性,增加破解难度。如果密码对应的数值是质数,由于其只有1和自身两个因数,在某些加密场景下会更难被暴力破解,所以我们认为是质数的密码数值在这方面有一定强度优势。同时,质因数分解也与密码强度相关,质因数数量越多,意味着密码数值的分解方式越复杂,暴力破解时需要尝试的组合更多,密码强度也就越高。另外,通过检查密码中是否包含特定数字组合,能从另一个角度评估密码安全性,若包含特殊数字组合,可能会被攻击者利用,降低密码强度。以下是该程序的部分代码,请你完善它。

#include <iostream>
#include <vector>
#include <cmath>

// 判断一个数是否为质数
bool isPrime(int num) {
    if (num <= 1) return false;
    for (int i = 2; i * i <= num; ++i) {
        if (____________________) {
            return false;
        }
    }
    return true;
}

// 找出一个数的所有因数
std::vector<int> findFactors(int num) {
    std::vector<int> factors;
    for (int i = 1; i <= num; ++i) {
        if (num % i == 0) {
            ____________________;
        }
    }
    return factors;
}

// 分解质因数
std::vector<int> primeFactorization(int num) {
    std::vector<int> primeFactors;
    for (int i = 2; i <= num; ++i) {
        while (____________________) {
            primeFactors.push_back(i);
            num /= i;
        }
    }
    return primeFactors;
}

// 根据质因数数量评估密码强度等级
int evaluatePasswordStrength(const std::vector<int>& primeFactors) {
    int strength = 0;
    // 假设质因数数量越多,密码强度越高
    strength = primeFactors.size();
    if (strength < 3) {
        return 1; // 低强度
    } else if (strength < 5) {
        return 2; // 中强度
    } else {
        return 3; // 高强度
    }
}

// 检查密码是否包含特定数字组合(模拟实际安全策略)
bool checkSpecialCombination(int password, int specialNumber) {
    std::string passwordStr = std::to_string(password);
    std::string specialStr = std::to_string(specialNumber);
    return ____________________;
}

// 使用快速幂算法计算密码数值的幂次方(新增知识点)
int fastPower(int base, int exponent) {
    int result = 1;
    while (exponent > 0) {
        if (exponent % 2 == 1) {
            result = result * base;
        }
        base = base * base;
        exponent = exponent / 2;
    }
    return result;
}

// 利用函数重载,实现不同数据类型的快速幂运算(新增知识点)
double fastPower(double base, int exponent) {
    double result = 1.0;
    while (exponent > 0) {
        if (exponent % 2 == 1) {
            result = result * base;
        }
        base = base * base;
        exponent = exponent / 2;
    }
    return result;
}

int main() {
    int password = 123456;
    std::cout << "密码数值: " << password << std::endl;

    std::cout << "该密码数值是否为质数: ";
    if (____________________) {
        std::cout << "是" << std::endl;
    } else {
        std::cout << "否" << std::endl;
    }

    std::vector<int> factors = findFactors(password);
    std::cout << "该密码数值的因数有: ";
    for (int factor : factors) {
        std::cout << factor << " ";
    }
    std::cout << std::endl;

    std::vector<int> primeFactors = primeFactorization(password);
    std::cout << "该密码数值的质因数分解为: ";
    for (int primeFactor : primeFactors) {
        std::cout << primeFactor << " ";
    }
    std::cout << std::endl;

    int strength = evaluatePasswordStrength(primeFactors);
    std::cout << "根据质因数数量评估的密码强度等级: " << strength << std::endl;

    int specialNumber = 34;
    if (checkSpecialCombination(password, specialNumber)) {
        std::cout << "密码包含特殊数字组合 " << specialNumber << ",可能存在风险" << std::endl;
    } else {
        std::cout << "密码不包含特殊数字组合 " << specialNumber << std::endl;
    }

    // 计算密码数值的5次幂
    int powerResult = fastPower(password, 5);
    std::cout << "密码数值的5次幂为: " << powerResult << std::endl;

    // 计算3.5的4次幂(测试函数重载)
    double doublePowerResult = fastPower(3.5, 4);
    std::cout << "3.5的4次幂为: " << doublePowerResult << std::endl;

    return 0;
}

1 条评论

  • @ 2025-10-1 15:59:07

    【选择题参考答案】 1- 5:CCBCB 6-10:BBBBC 11-15:BBBCB 16-20:BBCBA

    【阅读程序题 一】

    1. 题目 1:B。 代码中定义了两个同名函数 isPrime,但参数类型不同,这体现了 C++ 的函数重载特性,通过不同的参数列表来区分不同的函数,答案选 B。

    2. 题目 2:A。 isPrime(double num) 函数中,static_cast<int>(num) 是将浮点数 num 转换为整数,因为质数判断是针对整数进行的,转换后用于后续的质数判断逻辑,答案选 A。

    3. 题目 3:B。 在 generatePrimes 函数中,while (count < size) 循环的目的是找到 size 个质数,并将这些质数填充到动态分配的数组 primes 中,答案选 B。

    4. 题目 4:B。 按照质数的定义和 generatePrimes 函数的逻辑,从 2 开始依次判断每个数是否为质数,当找到 5 个质数时停止。前 5 个质数是 2, 3, 5, 7, 11,答案选 B。

    5. 题目 5:B。 在 main 函数中,delete[] primeArray; 用于释放 primeArray 所指向的动态分配的数组内存,防止内存泄漏,答案选 B。

    6. 题目 6:B。 代码中先将浮点数 testNum 转换为整数,再使用优化后的质数判断函数进行判断,所以结果是准确的,答案选 B。

    【阅读程序题 二】 参考答案:

    1. B(i=2,3,4,5时i²≤25,第5次i=6时退出)
    2. B(新节点插入头节点与第一个节点之间)
    3. C(递归计算4! = 24)
    4. C(2^5=32)
    5. D(失去平方优化,效率降低)
    6. B(后插入的7会排在5前面)

    解析要点:

    • 第1题:考察循环终止条件与数学计算能力
    • 第2题:验证链表操作的核心指针逻辑
    • 第3题:识别递归函数本质是阶乘计算
    • 第4题:测试快速幂算法的位运算理解
    • 第5题:分析算法优化的数学原理
    • 第6题:检测对头插法链表的构建顺序认知

    【阅读程序题 三】 题目 1:C。 while (file >> num) 中的 file >> num 用于从文件 file 中读取一个整数,并将其存储到 num 变量中,所以答案选 C。

    题目 2:A。 在分治递归算法中,int mid = (left + right) / 2; 通过计算数组的中间位置,将数组分成左右两部分,以便递归地计算两部分的和,答案选 A。

    题目 3:C。

    题目 4:B。 如果 readNumbersFromFile 函数无法打开文件,会执行 std::cerr << "无法打开文件: " << filename << std::endl; 输出错误信息,程序虽然不会立即崩溃,但后续对 numbers 向量的操作可能会导致未定义行为,从整体功能上可认为程序会因无法读取数据而终止预期功能,答案选 B。

    题目 5:D。 当 left > right 时,表示当前处理的数组范围为空,返回 0;当 left == right 时,表示当前处理的数组范围只有一个元素,返回该元素值,所以 A 和 B 说法都正确,答案选 D。

    题目 6:C。 在 main 函数中计算出 totalSum 之后统计奇数个数最合适,此时已经读取完文件中的所有数字,并且完成了总和的计算,然后在打开 result.txt 文件输出总和之前统计并输出奇数个数,不会影响原有功能逻辑,答案选 C。在 readNumbersFromFile 函数中统计不利于统一输出结果;在 divideAndConquerSum 函数中统计会破坏该函数原本的分治递归逻辑;在打开 result.txt 文件之后统计,若统计过程出现错误,可能导致文件已打开但未正确写入所有信息。

    【完善程序题】

    1. 第一处答案num % i == 0
    • 考察知识点:质数判断的核心逻辑。通过检查num能否被i整除来判断num是否为质数,考查对质数判断原理的理解。这里虽然和第三处判断条件代码相同,但在不同函数中有不同意义,第一处是在判断质数函数中,第三处是在质因数分解函数中,从不同角度考查对该判断条件的运用。
    1. 第二处答案factors.push_back(i)
    • 考察知识点:因数查找与std::vector容器操作。当找到num的因数i时,将其添加到factors向量中,考查对因数概念及std::vector使用方法的掌握。
    1. 第三处答案num % i == 0
    • 考察知识点:质因数分解的逻辑实现。在循环中,只要num能被i整除,就说明inum的质因数,考查对质因数分解过程的理解与运用。
    1. 第四处答案passwordStr.find(specialStr) != std::string::npos
    • 考察知识点:字符串查找操作。将整数转换为字符串后,利用std::stringfind函数查找特定数字组合,考查对字符串操作和类型转换的掌握。
    1. 第五处答案isPrime(password)
    • 考察知识点:函数调用及逻辑判断。在main函数中调用isPrime函数判断密码数值是否为质数,并根据返回结果输出相应信息,考查对函数调用及条件判断语句的运用。
    1. 新增知识点
      • 快速幂算法:通过fastPower函数实现快速幂算法,考查对快速幂算法原理和代码实现的理解。
      • 函数重载:通过对fastPower函数进行重载,实现不同数据类型(intdouble)的快速幂运算,考查对函数重载概念和使用方法的掌握。
    • 1