R3 GESP C++ 三级复习手册(B班通关宝典)

给 B 班同学的话:

GESP 三级是编程学习的第一个真正的分水岭。一二级考的大多是语法基础(顺序、分支、循环),而三级开始,计算机底层原理(原码补码、进制、位运算)和核心数据结构与算法(数组、字符串、枚举、模拟)全面登场!

很多同学看到“补码”、“位运算”就觉得难,其实这完全是纸老虎。本手册专为 B 班同学编写,特点是:零黑话、全图解、步步推演、自带避坑指南。你不需要翻阅其他讲义,这一本手册就把三级考纲的所有知识点、易错题和编程考法全部打包吃透!

三级及格线是 60 分。只要把本手册的前半部分客观题规律吃透(稳拿 35~40 分),再把第一道编程题做对(稳拿 25 分),你就已经稳过 60 分了!


考试档案与考纲全景

1. 考试基本信息

项目 内容
考试时长 120 分钟(2 小时)
试卷满分 100 分(60 分及格过关并获得证书)
题型分布 单选题 15 道(每题 2 分,共 30 分)
判断题 10 道(每题 2 分,共 20 分)
编程题 2 道(每题 25 分,共 50 分)
开发环境 Dev-C++ 5.11,标准为 C++11

2. GESP 三级知识模块导航

模块 考纲知识点 对应手册章节 考题形式 难度星级
M1 数据编码:原码、反码、补码 第一章 单选、判断 ★★★☆☆
M2 进位制与进制转换(二、八、十、十六) 第二章 单选、判断、编程填空 ★★☆☆☆
M3 位运算:&、|、~、^、<<、>> 第三章 单选、判断、编程 ★★★☆☆
M4 算法的概念与描述(自然语言、流程图、伪代码) 第四章 单选、判断 ★☆☆☆☆
M5 C++ 一维数组基本应用(定义、初始化、遍历、极值、统计) 第五章 编程题第 1 题核心 ★★☆☆☆
M6 字符串 std::string 及常用函数 第六章 编程题第 2 题核心 ★★★☆☆
M7 核心算法一:枚举法(穷举) 第七章 编程题 ★★☆☆☆
M8 核心算法二:模拟法 第八章 编程题 ★★☆☆☆
附录 B班必看:考场 5 大致命 Bug 抓虫实操 第九章 考场保命 ★★★★★
真题 GESP 三级全真题型实战演练(客观+编程) 第十章 综合自测 ★★★☆☆

第一章 数据编码(原码、反码、补码)

大纲要求: 了解二进制数据编码:原码、反码、补码。

计算机内部所有的数都是以二进制形式存储的,而且计算机的 CPU 内部只有加法器,没有减法器!为了用加法来算减法(比如 5−35 - 3 当成 5+(−3)5 + (-3) 算),计算机科学家发明了原码、反码、补码。

现代计算机中,所有整数一律用【补码】存储和运算!


1.1 最高位是“符号位”

在一个有固定位数的二进制数中(通常以 8 位 byte 为例):

       符号位(0正1负)
          ↓
          0 0 0 0 0 1 0 1   --> 这是 +5
          1 0 0 0 0 1 0 1   --> 这是 -5 的原码

1.2 正数的编码:三码合一

📝 金科玉律:正数的原码、反码、补码完全一模一样!根本不用算!

例如 +5+5(用 8 位二进制表示):


1.3 负数的编码:三步变身法

负数的原码、反码、补码各不相同,换算口诀如下:

          符号位填 1,后面写绝对值的二进制
负数数值 ──────────────────────────────────────────> 原码
                                                      │
                       符号位不变(仍为1),其余位按位取反 │ (0变1, 1变0)
                                                      ↓
                                                     反码
                                                      │
                                                      │ 加 1
                                                      ↓
                                                     补码

实战手推:求 −5-5 的 8 位原码、反码、补码

  1. 写原码:+5+5 是 0000 0101,负数符号位填 1 →\to 原码:1000 0101
  2. 变反码:符号位 1 保持不动,后面 7 位全部取反 →\to 反码:1111 1010
  3. 变补码:在反码的最后一位加上 1 →\to 补码:1111 1011

逆向推导:已知负数补码,怎么求原数值?

方法完全一样:取反再加 1(或者减 1 再取反)。


1.4 考场高频坑:8 位有符号数的范围是 −128∼+127-128 \sim +127

很多同学问:8 个二进制位能表示 28=2562^8 = 256 个状态,正数能到 +127+127,负数为什么能到 −128-128?


1.5 本章考点自测速练

  1. 8 位二进制补码 1111 1111 对应的十进制整数是多少?
  2. 十进制数 −9-9 的 8 位二进制补码是多少?
点击查看答案与解析
  1. 答案:−1-1
    • 符号位是 1,为负数。
    • 数值位取反:1000 0000,加 1 得:1000 0001,绝对值是 1,故为 −1-1。
    • 记住一个常识:全 1 的补码永远是 −1-1。
  2. 答案:1111 0111
    • +9+9 是 0000 1001;
    • 原码:1000 1001;
    • 反码:1111 0110;
    • 补码(反码+1):1111 0111。

第二章 进位制与进制转换

大纲要求: 掌握数据的进制转换:二进制、八进制、十进制、十六进制。

日常生活中我们习惯逢十进一(十进制),计算机硬件底层是高低电平(二进制),为了书写紧凑,编程中常借用八进制和十六进制。

进位制 英文与前缀标识 允许使用的数字符号 计数规则
二进制 Binary(代码前缀 0b,后缀 B) 0, 1 逢二进一
八进制 Octal(代码前缀 0,后缀 O/Q) 0, 1, 2, 3, 4, 5, 6, 7 逢八进一
十进制 Decimal(无前缀,后缀 D) 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 逢十进一
十六进制 Hexadecimal(代码前缀 0x,后缀 H) 0~9 以及 A(10), B(11), C(12), D(13), E(14), F(15) 逢十六进一

2.1 任意进制转十进制:按权展开求和法

📝 口诀:从右往左数,第 kk 位的数值 ×基数k\times \text{基数}^k(kk 从 0 开始算),全部加起来!

范例 1:二进制转十进制

(1101)2=1×23+1×22+0×21+1×20=8+4+0+1=13(1101)_2 = 1 \times 2^3 + 1 \times 2^2 + 0 \times 2^1 + 1 \times 2^0 = 8 + 4 + 0 + 1 = 13

范例 2:十六进制转十进制

(2B)16=2×161+B×160=2×16+11×1=32+11=43(2\text{B})_{16} = 2 \times 16^1 + \text{B} \times 16^0 = 2 \times 16 + 11 \times 1 = 32 + 11 = 43


2.2 十进制转任意进制:除基取余,倒序排列

📝 口诀:一直除以基数(2、8、16),记下余数;直到商为 0;把所有余数从下往上(倒序)抄下来!

范例:将十进制数 2525 转成二进制

  2 | 25 ...... 余数 1  (最后一位) ↑
    +----+                         │
  2 | 12 ...... 余数 0             │
    +----+                         │ 倒
  2 |  6 ...... 余数 0             │ 序
    +----+                         │ 抄
  2 |  3 ...... 余数 1             │
    +----+                         │
  2 |  1 ...... 余数 1  (第一位)   │
    +----+
       0
结果:25 = (11001)₂

2.3 考场秒杀技:二进制与八进制、十六进制极速互转

因为 8=238 = 2^3,16=2416 = 2^4,它们之间互转根本不需要先转十进制,直接分组即可!

【二进制 <---> 八进制】: 3 位一组(4-2-1 原则)
二进制:    0 0 1   1 0 1   0 1 0
八进制:      1       5       2    ==> (152)₈

【二进制 <---> 十六进制】:4 位一组(8-4-2-1 原则)
二进制:    0 1 1 0    1 1 0 1
十六进制:     6          D        ==> (6D)₁₆   (注意 13 对应 D)

⚠️ 注意:分组时必须从小数点或最右边(个位)开始向左分,左边不够位数的补 0!


2.4 C++ 代码中的进制输入与输出

GESP 编程题经常考进制输出,C++ 标准库带有一套极其方便的格式控制符:

#include <bits/stdc++.h>
using namespace std;

int main() {
    int n = 43;

    // 输出十进制、八进制、十六进制
    cout << dec << n << endl;   // 输出 43 (dec: decimal)
    cout << oct << n << endl;   // 输出 53 (oct: octal)
    cout << hex << n << endl;   // 输出 2b (hex: hexadecimal)

    // 代码中直接书写不同进制字面量
    int a = 0b1011;   // 二进制 11
    int b = 052;      // 八进制 42 (以 0 开头)
    int c = 0x2A;     // 十六进制 42 (以 0x 开头)
    cout << a << " " << b << " " << c << endl; // 默认均按十进制输出: 11 42 42
    return 0;
}

第三章 位运算(Bitwise Operations)

大纲要求: 掌握位运算:与(&)、或(|)、非(~)、异或(^)、左移(<<)、右移(>>)的基本使用方法及原理。

位运算就是直接对整数在内存中的二进制位进行操作。速度极快,是计算机最高效的运算。


3.1 六大运算符号与真值表

我们用一位二进制(只有 0 和 1)来建立口诀:

运算符 名称 规则口诀 运算法则 示例 (a=5(0101)2,b=3(0011)2a=5(0101)_2, b=3(0011)_2)
& 按位与 全 1 才是 1,有 0 则为 0 1&1=1,1&0=0,0&0=01\&1=1,\ 1\&0=0,\ 0\&0=0 a&b=(0001)2=1a \& b = (0001)_2 = 1
| 按位或 有 1 就是 1,全 0 才是 0 1|0=1,1|1=1,0|0=01|0=1,\ 1|1=1,\ 0|0=0 a|b=(0111)2=7a | b = (0111)_2 = 7
^ 按位异或 相同为 0,不同为 1(求异) 1^1=0,0^0=0,1^0=11\text{^}1=0,\ 0\text{^}0=0,\ 1\text{^}0=1 a^b=(0110)2=6a \text{^} b = (0110)_2 = 6
~ 按位非(取反) 黑白颠倒,0变1,1变0 ∼1=0,∼0=1\sim 1 = 0,\ \sim 0 = 1 包含符号位全部翻转
<< 左移 所有位向左推,低位补 0 每左移 1 位,相当于 ×2\times 2 a≪1=(1010)2=10a \ll 1 = (1010)_2 = 10
>> 右移 所有位向右推,低位丢弃 每右移 1 位,相当于 ÷2\div 2(向下整除) a≫1=(0010)2=2a \gg 1 = (0010)_2 = 2

3.2 必须背诵的 4 个位运算实战神技

  1. 判断整数 nn 是奇数还是偶数:
  2. 乘以或除以 2k2^k:
  3. 异或的奇妙特性(考场超高频):
  4. 提取或去掉最低位的 1:

3.3 ⚠️ 考场头号杀手:位运算符优先级极低!

很多同学写下这行代码,怎么调都 WA(答案错误):

if (n & 1 == 0) // ❌ 严重错误!

为什么错? 因为在 C++ 中,关系运算符 == 的优先级远高于按位与 &! 上面的代码被系统自动理解成了:

if (n & (1 == 0))  --> 变成了 if (n & 0) --> 永远是假(false)!

📝 保命法则:只要写位运算,必须给位运算加括号!无条件写成:if ((n & 1) == 0)


第四章 算法的概念与描述

大纲要求: 了解算法的概念与描述,熟练运用自然语言、流程图、伪代码方式来描述算法。

4.1 什么是算法?算法的 5 大特征

算法就是解决问题的一系列明确指令与计算步骤。不是所有过程都能叫算法,算法必须同时具备 5 大特性(选择题必考):

  1. 有穷性:算法必须在执行有限步之后结束,不能陷入无限死循环。
  2. 确定性:算法的每一步骤必须有明确的定义,不能模棱两可、含糊不清。
  3. 可行性:算法中的每一步操作都是可以通过有限次基本运算实现的。
  4. 输入:有零个或多个输入。
  5. 输出:至少有一个或多个输出(没有输出的算法毫无意义)。

4.2 算法的三种描述方法

描述方式 特点 优缺点
自然语言 用中文/英文文字逐步叙述(如“第一步...第二步...”) 通俗易懂,但容易产生歧义、文字冗长
流程图 用统一规范的几何图形框和箭头表示 直观清晰、逻辑顺序一目了然,但绘制繁琐
伪代码 介于自然语言与编程语言之间(类似不写头文件的精简代码) 结构分明、书写自由、方便直接转换成 C++ 代码

流程图标准规范图形(选择题常客)

    ╭──────────╮
    │  开始/结束 │       <-- 圆角矩形 / 椭圆形:表示算法的【起止】
    ╰─────┬────╯
          │
          ▼
    /    输入/输出   /    <-- 平行四边形:表示数据的【输入或输出】
    /─────────────/
          │
          ▼
    ┌──────────┐
    │   处理框   │       <-- 矩形:表示计算、赋值、数据处理
    └─────┬────╯
          │
          ▼
        /  \
       / 条件 \          <-- 菱形:表示【判断/分支】(根据真假分两路走)
       \ 判定 /
        \  /

4.3 读懂伪代码实战

GESP 单选题常给出一段伪代码,问输出是什么。看懂伪代码的绝招是:在草稿纸上画表格,一步一步模拟变量的变化(跟踪变量法)。

伪代码示例:
输入 N
ans <- 0
i <- 1
WHILE i <= N DO
    IF i MOD 2 = 0 THEN
        ans <- ans + i
    END IF
    i <- i + 1
END WHILE
输出 ans

分析:MOD 是取余 %,<- 是赋值 =。 这就是在统计 1∼N1 \sim N 之间所有偶数的和!若输入 N=6N=6,偶数是 2, 4, 6,输出就是 2+4+6=122+4+6=12。


第五章 C++ 一维数组基本应用

大纲要求: C++ 一维数组基本应用(不包括变长数组),包括定义、初始化、遍历、求和、最大最小值、统计等。

变量就像一个单个储物格,而数组就是一整排编号相连的储物柜。


5.1 数组定义与初始化

// 1. 数组定义:类型 数组名[固定长度];
int a[10];           // 定义了一个长度为 10 的整型数组,下标是 0 到 9!

// 2. 初始化全为 0(极度推荐)
int b[10] = {0};     // 10 个格子全部初始化为 0

// 3. 部分显式初始化
int c[5] = {1, 2};   // 前两个是 1, 2,后面三个自动补 0:1, 2, 0, 0, 0

⚠️ B 班最致命警示:下标永远从 0 开始! 定义 int a[10];,合法的格子只有:a[0], a[1], a[2], ..., a[9]。 根本不存在 a[10]! 访问 a[10] 叫数组下标越界,考试会导致死机或被判 0 分!


5.2 全局数组 vs 局部数组


5.3 一维数组的 5 大固定操作套路(编程题 1 必备)

套路 1:批量读入与打印

int n;
cin >> n;
int a[1005];
for (int i = 0; i < n; i++) {
    cin >> a[i];  // 从 0 循环到 n-1 读入
}
for (int i = 0; i < n; i++) {
    cout << a[i] << " ";
}
cout << endl;

套路 2:累加求和与平均值

long long sum = 0; // 求和变量记得先清 0!
for (int i = 0; i < n; i++) {
    sum += a[i];
}
double avg = (double)sum / n; // ⚠️ 注意强转 double,保留小数

套路 3:打擂台法找最大值与最小值(最常考)

int max_val = a[0]; // 先让第 0 个人当擂主!
int max_idx = 0;    // 记录最大值所在的下标

for (int i = 1; i < n; i++) {
    if (a[i] > max_val) {
        max_val = a[i]; // 发现更厉害的,新擂主上位
        max_idx = i;
    }
}
cout << "最大值是 " << max_val << ",位置是 " << max_idx << endl;

⚠️ 坑点:找最大值千万不要盲目把初值设为 0!如果数组里全是负数(比如 -5, -10, -3),初值写 0 输出结果就会错成 0!最佳初值永远是 a[0]。

套路 4:条件计数(统计及格人数)

int count_pass = 0;
for (int i = 0; i < n; i++) {
    if (a[i] >= 60) {
        count_pass++;
    }
}

套路 5:数组逆序(首尾对调双指针法)

// 将 a 数组就地翻转
int l = 0, r = n - 1;
while (l < r) {
    swap(a[l], a[r]); // 交换首尾元素
    l++;
    r--;
}

第六章 字符串(std::string)与字符操作

大纲要求: 掌握字符串及其函数的使用,包括但不限于大小写转换、字符串搜索、分割、替换。

在 C++ 中,推荐使用强大的 string 类(需要包含头文件 <string> 或 <bits/stdc++.h>)。


6.1 字符串的读入与访问

  1. 读入单个单词(不含空格):cin >> s;(遇到空格或回车就停止)。
  2. 读入整行(包含空格):getline(cin, s);。
  3. 获取长度:s.size() 或 s.length()。
  4. 按下标访问字符:s[0] 是第 1 个字符,s[s.size() - 1] 是最后一个字符。
字符串: "H  e  l  l  o"
下标:    0  1  2  3  4     (长度 s.size() 是 5)

⚠️ 避坑秘笈:cin >> 与 getline 混用的换行残留坑 如果先用 cin >> n 读了一个数字,紧接着用 getline(cin, s) 读一整行,你会发现 s 读到的是个空串!因为 cin >> n 把末尾的回车符留在了缓冲区里。 解法:在 getline 之前加一句 cin.ignore(); 吃掉回车!

cin >> n;
cin.ignore(); // 关键!清空回车
getline(cin, s);

6.2 字符串的 5 个王牌函数(背诵过关)

#include <bits/stdc++.h>
using namespace std;

int main() {
    string s = "Hello C++ World";

    // 1. 截取子串: s.substr(起始位置, 截取长度)
    string sub = s.substr(6, 3); // 从下标 6 开始切 3 个字符
    cout << sub << endl;         // 输出 "C++"

    // 2. 查找子串: s.find(目标串)
    // 找到了返回第一次出现的下标;找不到返回 string::npos (不要写 -1)
    int pos = s.find("C++");
    if (pos != string::npos) {
        cout << "找到了,下标在:" << pos << endl; // 6
    }

    // 3. 替换子串: s.replace(起始位置, 替换长度, 新串)
    s.replace(6, 3, "Python");
    cout << s << endl;           // "Hello Python World"

    // 4. 字符串拼接
    string a = "Good", b = "Job";
    string c = a + " " + b;      // "Good Job"

    // 5. 字符串反转 (使用 <algorithm> 里的 reverse)
    string rev = "12345";
    reverse(rev.begin(), rev.end());
    cout << rev << endl;         // "54321"

    return 0;
}

6.3 单个字符的大小写转换与数字转换

需求 标准写法 原理说明
判断是否是大写字母 if (c >= 'A' && c <= 'Z') 或 isupper(c) 利用 ASCII 码连续性
判断是否是数字字符 if (c >= '0' && c <= '9') 或 isdigit(c) 字符 '0' 是 48
大写转小写 c = tolower(c); 或 c = c + 32; 小写比大写大 32
小写转大写 c = toupper(c); 或 c = c - 32; 大写比小写小 32
数字字符转对应整数 int num = c - '0'; 比如 '7' - '0' = 7
整数转数字字符 char c = num + '0'; 比如 7 + '0' = '7'

第七章 核心算法一:枚举法(穷举法)

大纲要求: 理解枚举算法的原理及特点,可以解决实际问题。

7.1 枚举的核心思想

枚举法(又称“笨办法”或暴力求解):把所有可能的答案一个一个拿来检验,符合题目条件的就留下,不符合的就扔掉。

📝 B 班枚举三步法:

  1. 枚举谁?(确定循环变量,例如从 1 到 nn);
  2. 范围多大?(初始值是谁?结束值是谁?例如水仙花数范围是 100∼999100 \sim 999);
  3. 怎么验证?(写一个 if 语句,符合条件的统计或打印)。

7.2 经典真题模板:水仙花数

问题:求所有三位数中,各位数字立方和等于该数本身的数字(如 153=13+53+33153 = 1^3 + 5^3 + 3^3)。

#include <bits/stdc++.h>
using namespace std;

int main() {
    // 1. 明确范围:所有三位数就是 100 到 999
    for (int i = 100; i <= 999; i++) {
        // 2. 分解各位数字
        int g = i % 10;         // 个位
        int s = (i / 10) % 10;  // 十位
        int b = i / 100;        // 百位

        // 3. 条件判断
        if (b * b * b + s * s * s + g * g * g == i) {
            cout << i << " ";
        }
    }
    cout << endl;
    return 0;
}

输出:153 370 371 407。


7.3 枚举优化技巧:少枚举一重循环

百钱买百鸡:公鸡 5 元一只,母鸡 3 元一只,小鸡 1 元三只。用 100 元买 100 只鸡。


第八章 核心算法二:模拟法

大纲要求: 理解模拟算法的原理及特点,可以解决实际问题。

8.1 什么是模拟法?

模拟法就是题目怎么说,你就让代码怎么一步一步走。 题目是考官出的剧本,代码是演员,按照剧本分毫不差地演一遍。

📝 模拟法核心三步:

  1. 定义状态:用哪些变量表示当前的情况?
  2. 推进一步:状态如何发生变化?(如时间加 1、小人走一步、数字发生改变);
  3. 结束条件:什么时候停止?

8.2 经典模拟:角谷猜想(3n+1 问题)

题目描述:给定一个正整数 nn。如果是奇数,乘 3 加 1;如果是偶数,除以 2。重复该过程,直到 nn 变成 1。输出一共变换了多少次。

#include <bits/stdc++.h>
using namespace std;

int main() {
    long long n; // 过程中可能超出 int 范围,稳妥起见开 long long
    cin >> n;
    int step = 0;

    // 终止条件:n == 1
    while (n != 1) {
        if (n % 2 == 1) {
            n = n * 3 + 1; // 奇数:乘3加1
        } else {
            n = n / 2;     // 偶数:除以2
        }
        step++;            // 步数累加
    }

    cout << step << endl;
    return 0;
}

第九章 B 班保命:考场 5 大致命 Bug 抓虫示范

很多同学自学了很久,知识点全都会,一考就只有 40 分。以下是 B 班最容易丢分的 5 大坑,请当成考前疫苗仔细研读!


❌ 坑 1:位运算优先级导致判断失效

// 错误写法:
if (x & 1 == 0)  // 编译器先算 1 == 0 (得 0),变成 if(x & 0),永远不成立!

// ✅ 正确保命写法:必须带外层括号
if ((x & 1) == 0)

❌ 坑 2:求最大值初值错设为 0

// 错误写法:
int max_val = 0; 
for (int i = 0; i < n; i++) {
    if (a[i] > max_val) max_val = a[i];
}
// 如果输入数组全是负数:-10, -5, -8
// 输出是 0!实际上答案应该是 -5!

// ✅ 正确保命写法:直接用第 0 个元素当擂主
int max_val = a[0];
for (int i = 1; i < n; i++) {
    if (a[i] > max_val) max_val = a[i];
}

❌ 坑 3:一维数组越界访问

int a[100];
int n;
cin >> n; // 假设 n = 100
for (int i = 1; i <= n; i++) cin >> a[i]; // 当 i = 100 时,访问了 a[100]!越界!

// ✅ 正确保命写法:
// 习惯 1:大小多开 10 个空间!比如范围是 100,数组就开 110:int a[110];
// 习惯 2:严格使用 0 到 n-1 下标:for(int i = 0; i < n; i++) cin >> a[i];

❌ 坑 4:整数除法丢失小数

int a = 7, b = 2;
double ans = a / b;         // ❌ 结果是 3.0,不是 3.5!因为 a/b 先按 int 算成了 3

// ✅ 正确保命写法:至少一边强制转 double
double ans = (double)a / b; // 3.5
// 或者:
double ans = a * 1.0 / b;   // 3.5

❌ 坑 5:cin 与 getline 换行遗留

int n;
string s;
cin >> n;
getline(cin, s); // ❌ 此时 s 读到的是 n 后面的回车符,是空串!

// ✅ 正确保命写法:
cin >> n;
cin.ignore();    // 把回车符吃掉
getline(cin, s); // 顺利读入后面的整行文本

第十章 GESP 三级全真题型实战演练

10.1 客观题实战精选(6 道经典考题)

【题 1·单选题】 在计算机内部,有符号整数通常采用下列哪种编码形式进行存储和计算? A. 原码
B. 反码
C. 补码
D. ASCII 码

【解析】 答案为 C。现代计算机体系结构中,为了统一加减法并消除 +0+0 和 −0-0 的歧义,所有整数一律采用补码。


【题 2·单选题】 十六进制数 0x2F 转换成十进制数是( )。 A. 45
B. 47
C. 57
D. 31

【解析】 答案为 B。按权展开:2×161+F×160=32+15=472 \times 16^1 + \text{F} \times 16^0 = 32 + 15 = 47。


【题 3·单选题】 表达式 (7 & 3) | (8 >> 2) 的计算结果是( )。 A. 2
B. 3
C. 5
D. 7

【解析】 答案为 B。


【题 4·单选题】 8 位二进制补码 1000 0000 表示的十进制整数是( )。 A. 0
B. -127
C. -128
D. 128

【解析】 答案为 C。这是考纲明文规定的边界特值,8 位补码 1000 0000 规定代表 −128-128。


【题 5·判断题】 在 C++ 语言中,定义数组 int a[5]; 后,访问 a[5] 在语法上一定能通过编译,但运行时属于未定义行为(越界)。( ) A. 正确
B. 错误

【解析】 答案为 A。C++ 编译器通常不检查静态数组下标越界,能正常编译,但运行期非法访问会导致程序异常,考场严禁越界。


【题 6·单选题】 阅读以下伪代码,若输入为 5,输出结果是( )。

输入 N
s <- 1
i <- 1
WHILE i <= N DO
    s <- s * i
    i <- i + 1
END WHILE
输出 s

A. 15
B. 25
C. 120
D. 720

【解析】 答案为 C。变量跟踪:i=1,s=1→i=2,s=2→i=3,s=6→i=4,s=24→i=5,s=120i=1, s=1 \to i=2, s=2 \to i=3, s=6 \to i=4, s=24 \to i=5, s=120。实际上计算的是 5 的阶乘 5!=1205! = 120。


10.2 编程题实战演练

编程实战 1:校门外的统计(一维数组与模拟)

题目描述: 某学校组织期中测试,有 nn 名学生(1≤n≤10001 \le n \le 1000)。给出每名学生的成绩(0∼1000 \sim 100 的整数)。 请你编写程序,计算并输出:

  1. 全班最高分;
  2. 全班平均分(保留两位小数);
  3. 高于(大于)平均分的人数。

输入样例:

5
80 90 70 60 100

输出样例:

100
80.00
2
【解题思路与自学脚手架】
  1. 输入与存储:n≤1000n \le 1000,开一个大小为 1005 的全局数组 a。
  2. 第一遍遍历:
  3. 计算平均分:double avg = (double)sum / n;。
  4. 第二遍遍历:数一数有几个同学的成绩严格大于 avg。
【标准参考代码】
#include <bits/stdc++.h>
using namespace std;

int a[1005];

int main() {
    int n;
    if (!(cin >> n)) return 0;

    long long sum = 0;
    int max_score = -1; // 成绩非负,初值设 -1 极其安全

    for (int i = 0; i < n; i++) {
        cin >> a[i];
        sum += a[i];
        if (a[i] > max_score) {
            max_score = a[i];
        }
    }

    double avg = (double)sum / n;

    int above_cnt = 0;
    for (int i = 0; i < n; i++) {
        if (a[i] > avg) {
            above_cnt++;
        }
    }

    // 格式化输出
    cout << max_score << endl;
    cout << fixed << setprecision(2) << avg << endl;
    cout << above_cnt << endl;

    return 0;
}

编程实战 2:字符串清洗与字符统计(字符串综合题)

题目描述: 输入一行字符串(可能包含大小写字母、数字、空格和特殊字符,长度不超过 200)。 请进行如下处理并按格式输出:

  1. 将所有的大写字母转换成小写字母;
  2. 统计其中数字字符(0~9)的总个数;
  3. 输出处理后的新字符串,并在下一行输出数字字符的总数。

输入样例:

CSP 2026 Junior & GESP Grade 3!

输出样例:

csp 2026 junior & gesp grade 3!
5
【解题思路与自学脚手架】
  1. 整行读入:因为包含空格,绝不能用 cin >> s;,必须使用 getline(cin, s);!
  2. 字符遍历与变换:
【标准参考代码】
#include <bits/stdc++.h>
using namespace std;

int main() {
    string s;
    getline(cin, s); // 整行读入,包含空格

    int digit_cnt = 0;

    for (int i = 0; i < (int)s.size(); i++) {
        // 统计数字个数
        if (s[i] >= '0' && s[i] <= '9') {
            digit_cnt++;
        }
        // 转换小写
        s[i] = tolower(s[i]);
    }

    cout << s << endl;
    cout << digit_cnt << endl;

    return 0;
}

考前冲刺 30 秒通关自检

每位 B 班同学在考前一晚,请对着以下 7 个问题默问自己,能够脱口而出就算达标:

祝所有 B 班同学稳定发挥,一次高分通过 GESP 三级认证!