R1 GESP C++ 一级复习手册

打印说明: 这份手册是给你打出来放在桌上翻的,所以全文没有折叠答案——所有参考代码和解析都直接排在题目下面。建议 A4 双面打印。


这份手册是什么

对照 CCF 编程能力等级认证 C++ 一级标准,把 13 条考点全部覆盖一遍。

考试怎么考

题型 题量 每题分 小计
单选题 15 道 2 分 30 分
判断题 10 道 2 分 20 分
编程题 2 道 25 分 50 分

考试时间 120 分钟,满分 100 分。

⚠️ 注意这个分数结构:选择题 + 判断题 = 50 分,和编程题一样多。 而这 50 分里有相当一部分考的是计算机基础常识——课上从来没讲过,也不需要写代码,背下来就是分。第四节那张速记表,是本册性价比最高的一页。

怎么用这份手册

  1. 先看第一节的考纲对照表,勾出你没把握的条目
  2. 已学的部分(第二节)只用来查,别从头读
  3. 没学过的部分(第三节)要动手把代码敲一遍,光看没用
  4. 第五节的选择判断题先做再对答案
  5. 第六节编程题先自己写,写完再看参考代码

⚠️ 课堂上的"盲写热身"环节,这本手册不许带上桌。 手册是复习用的,盲写是检验用的——两件事不能混。


一、考纲对照表

一级考点 学过没有 看哪里
(1) 计算机基本构成、操作系统、发展历程 ❌ 没讲过 第四节
(2) 集成开发环境(Dev-C++)的使用 ✅ L01 第二节
(3) cin / cout / 赋值语句 ✅ L01 第二节
(3) scanf / printf ❌ 没讲过 3.4
(4) 标识符、关键字、常量、变量、表达式 ❌ 没讲过 3.5
(5) 变量的命名、定义、初始化与赋值 ✅ L01 第二节
(5) 自加自减运算 ++ / -- ❌ 没讲过 3.3
(6) 算术:加减乘除、整除、求余 ✅ L02 第二节
(7) 逻辑运算 && || ! ✅ L02 第二节
(8) 关系运算 > >= < <= == != ✅ L02 第二节
(9) 基本类型:int double char ✅ L01 / L05 第二节
(9) 基本类型:long long float bool 🟡 只提过 3.6
(10) 顺序结构 ✅ L01 第二节
(11) 分支:if / if-else ✅ L02 第二节
(11) 分支:switch ❌ 没讲过 3.1
(11) 三目运算 ? : ✅ L02 加餐 第二节
(12) 循环:for / while / break / continue ✅ L03 第二节
(12) 循环:do-while ❌ 没讲过 3.2
(13) 程序的注释与调试 🟡 零散 3.7

📝 一共 7 个缺口,全在第三节。 都是小知识点,一个下午能补完。


二、已学部分速查(只查不读)

2.1 Python → C++ 对照总表

Python C++ 备注
print("abc") cout << "abc" << endl; endl 换行
n = int(input()) int n; cin >> n; 先声明类型
a, b = map(int, input().split()) int a, b; cin >> a >> b; 连读
x = 10 int x = 10; 第一次出现要写类型
price = 3.5 double price = 3.5; 小数用 double
name = "abc" string name = "abc"; 文字用 string
# 注释 // 注释
缩进表示层级 { } 表示层级 机器只看大括号
行末不加符号 行末加 ; 最高频错误
7 / 2 → 3.5 7 / 2 → 3 ⚠️ 整数相除只留整数
7 // 2 7 / 2 C++ 的 / 就是整除
7 % 2 7 % 2 一样
2 ** 10 没有 ** 一级不考乘方
if x > 0: if (x > 0) { 条件必须加 ( )
elif else if 拆成两个词
and / or / not && / || / !
0 < x < 10 x > 0 && x < 10 ⚠️ 连写在 C++ 里是错的
a if a > b else b a > b ? a : b 三目运算符
while cond: while (cond) { 条件加括号
range(n) for (int i=0; i<n; i++) 0 到 n−1
range(a, b) for (int i=a; i<b; i++) a 到 b−1
range(n, 0, -1) for (int i=n; i>0; i--) 倒着数
break / continue break / continue 一模一样

2.2 固定模板(必须能默写)

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

int main() {
    // 你的代码写在这里
    return 0;
}

2.3 运算符优先级(考试常考)

从高到低:

级别 运算符
1(最高) ()
2 !++--、正负号
3 * / %
4 + -
5 > >= < <=
6 == !=
7 &&
8 ||
9(最低) =(赋值)

📝 记不住就加括号。 加括号从来不会错,猜优先级经常错。

2.4 已经踩过的坑

症状 原因
expected ';' before ... 上一行末尾漏分号
expected '(' before ... if / while 条件忘加小括号
编译过但结果永远一样 == 写成了 =
除法结果总是整数 两个 int 相除,要写 a * 1.0 / b
程序卡住不动 忘了让循环变量变化(死循环)
if 只管住了一句 没写大括号

三、新增考点精讲

3.1 switch 语句

考纲原文(11): 掌握分支结构程序的编写,掌握 if 语句、if-else 语句、switch 语句,了解三目运算。

switch 用来替代「拿同一个变量和一串具体的值逐个比较」的 if-else 链。

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

int main() {
    int day;
    cin >> day;

    switch (day) {           // 括号里放要判断的那个变量(必须是整数或字符)
        case 1:              // 如果 day 等于 1
            cout << "星期一" << endl;
            break;           // 跳出 switch,非常重要
        case 6:
        case 7:              // 两个 case 挨着写 = 6 和 7 走同一段代码
            cout << "周末" << endl;
            break;
        default:             // 都不匹配时走这里,相当于 else
            cout << "工作日" << endl;
            break;           // default 在最后时 break 可省,但建议写上
    }
    return 0;
}

输入 1 输出 星期一;输入 67 输出 周末;输入 3 输出 工作日

和 if-else 的对应关系:

switch 等价的 if 写法
switch (x) {
case 1: if (x == 1)
case 2: else if (x == 2)
default: else
break; (if 结构自带,不需要)

⚠️ 坑一:漏写 break 会「穿透」。

switch (day) {
    case 1:
        cout << "星期一" << endl;    // 漏了 break
    case 2:
        cout << "星期二" << endl;
        break;
}

输入 1 会输出两行星期一星期二。因为 case 只是一个入口标签,进去之后会一直往下执行,直到遇到 break 或者 }

📝 这是 GESP 一级最高频的选择题考点之一,每次考试几乎必出。

⚠️ 坑二:case 后面只能跟常量,不能跟范围或变量。

case x > 60:        // 错,不能写条件
case 60...100:      // 错,C++ 没有这个语法
case n:             // 错,n 是变量

case 后面必须是一个写死的整数或字符,比如 case 1:case 'A':

📝 所以「分数 ≥ 60 算及格」这种范围判断不能直接用 switch,要用 if-else。 但可以先 score / 10 把范围压成 0~10 这 11 个具体值,再用 switch——第六节的编程题 2 就是这么做的。

3.2 do-while 循环

考纲原文(12): 掌握循环结构程序的编写,掌握 for、while、do-while 循环语句的使用。

while先判断再执行do-while先执行再判断——所以 do-while 的循环体至少会执行一次

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

int main() {
    int n;
    cin >> n;

    int cnt = 0;             // 统计 n 有几位数字
    do {                     // 先干一次,再问要不要继续
        n = n / 10;          // 砍掉最右边一位
        cnt++;
    } while (n > 0);         // ⚠️ 这里的分号不能漏

    cout << cnt << endl;
    return 0;
}

输入 375 输出 3;输入 0 输出 1

📝 为什么这里必须用 do-while 因为 n = 0 时,while (n > 0) 一次都不会进循环,会输出 0 ——但 0 是一位数,正确答案是 1。do-while 先执行一次,天然处理了这个边界。

三种循环的对比:

循环 判断时机 最少执行 典型用途
for 先判断 0 次 知道要循环几次
while 先判断 0 次 不知道次数,看条件
do-while 后判断 1 次 至少要做一次的事

⚠️ 坑:while (条件) 后面的分号。

do {
    ...
} while (n > 0)          // 漏了分号

do-while 是唯一一个结尾要写分号的循环。forwhile} 后面不写分号,do-while 必须写。报错通常是 expected ';' before ...

3.3 自增自减 ++--

考纲原文(5): 掌握……变量的自加与自减运算

a++ 等价于 a = a + 1a-- 等价于 a = a - 1Python 没有这两个运算符(Python 写 a += 1)。

单独成一行时,a++++a 完全一样。 区别只在于把它写进表达式的时候:

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

int main() {
    int a = 5;
    int b = a++;         // 后置:先把 a 的旧值 5 给 b,然后 a 才变 6
    cout << a << " " << b << endl;    // 输出 6 5

    int c = 5;
    int d = ++c;         // 前置:先让 c 变 6,再把 6 给 d
    cout << c << " " << d << endl;    // 输出 6 6

    return 0;
}

输出:

6 5
6 6

📝 一句话记法:++加,++加。 加号的位置,就是加法发生的时机。

⚠️ 坑:别在一个表达式里对同一个变量用两次。

int a = 5;
int b = a++ + ++a;      // 结果在不同编译器上可能不一样

这在 C++ 里是未定义行为,不同编译器算出的结果可能不同。考试不会考这种,你也永远别这么写。

📝 实际写代码时,绝大多数场合都单独成行用i++cnt++),这时候前置后置没有区别,用哪个都行。

3.4 scanfprintf

考纲原文(3): 掌握基础的 cin 语句、scanf 语句、cout 语句、printf 语句,赋值语句等。

这是从 C 语言继承来的一套输入输出,cin/cout,格式控制也更方便。考试会考它们的格式符

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

int main() {
    int n;
    double x;
    char c;

    scanf("%d", &n);         // ⚠️ 读变量要加 & (取地址符)
    scanf("%lf", &x);        // double 用 %lf
    scanf(" %c", &c);        // 读字符前加一个空格,跳过之前残留的换行

    printf("%d\n", n);       // 输出整数;\n 就是换行,相当于 endl
    printf("%.2f\n", x);     // 输出小数,保留 2 位
    printf("%c\n", c);       // 输出字符

    return 0;
}

输入 3753.14159A,输出:

375
3.14
A

格式符对照表(背下来):

格式符 对应类型 备注
%d int 最常用
%lld long long 两个小写 L
%f float
%lf double scanf 必须用 %lf
%c char 单个字符
%s 字符数组 ⚠️ 不能读 string
%.2f 保留 2 位小数 只用于 printf

⚠️ 坑一:scanf 漏写 &

scanf("%d", n);          // 漏了 &

编译只给警告,运行直接崩溃。scanf 要改变变量的值,必须告诉它变量在哪儿,所以要 &printf 只是读出来打印,不需要 &

📝 一句话记法:往变量里"装"东西要 &,从变量里"取"东西不要。

⚠️ 坑二:printf 输出 double%f,但 scanfdouble 必须用 %lf 这一对不对称,是考试的常见陷阱。

3.5 标识符、关键字、常量、变量、表达式

考纲原文(4): 掌握标识符、关键字、常量、变量、表达式的概念。

这一条全是选择题考点,不需要写代码,但必须分清四个词。

① 标识符(identifier) = 你给变量、函数起的名字

命名规则(考试必考):

规则 说明
只能用字母、数字、下划线 _ 不能有空格、-#
不能以数字开头 2sum ❌,sum2
区分大小写 Sumsum 是两个不同的名字
不能是关键字 intfor 不能拿来当变量名
合法:   sum   _count   n1   maxValue   student_age
不合法: 2sum(数字开头)  my-name(有减号)  int(是关键字)  my name(有空格)

② 关键字(keyword) = C++ 自己占用的词,有特殊含义,不能当名字用。

常见的:int double char bool float long short if else switch case default for while do break continue return void const true false

📝 main 不是关键字,它只是一个约定俗成的函数名——这是考试爱考的细节。同理 cincoutendl不是关键字,它们是标准库里的名字。

③ 常量(constant) = 值不会变的量。

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

int main() {
    const double PI = 3.14159;   // const 表示"这个值定死了,不许再改"
    int r = 3;
    cout << PI * r * r << endl;  // 输出 28.2743
    // PI = 3.14;                // 如果放开这一行,编译会直接报错
    return 0;
}

常量分两类:

类型 例子
字面常量 103.14'A'"hello"
符号常量 const double PI = 3.14159;

④ 变量(variable) = 值可以变的量,用之前必须先声明类型。

⑤ 表达式(expression) = 由变量、常量、运算符组成、能算出一个值的式子。

a + b            是表达式,值是两数之和
a > b            是表达式,值是 1 或 0
a = b + 1        是表达式,值是赋值后 a 的值
cout << a;       不是表达式,是语句

📝 表达式后面加分号就变成语句(statement)。 「表达式有值,语句是动作」——这句话足够应付考试。

3.6 补齐三个基本类型

考纲原文(9): 掌握基础的数据类型的定义和使用(整型、实数型、字符型、布尔型)。

L01 只正式教了 int / double / string,这里把考纲要求的其余几个补上。

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

int main() {
    int a = 2100000000;              // 整型,约 ±21 亿
    long long b = 9000000000LL;      // 长整型,约 ±922 亿亿,后面加 LL
    float f = 3.14f;                 // 单精度小数,约 7 位有效数字
    double d = 3.141592653589;       // 双精度小数,约 15 位,平时都用它
    char c = 'A';                    // 字符,单引号,只能装一个
    bool flag = true;                // 布尔,只能是 true 或 false

    cout << a << endl;
    cout << b << endl;
    cout << f << endl;
    cout << d << endl;
    cout << c << endl;
    cout << flag << endl;            // ⚠️ 输出的是 1,不是 true
    return 0;
}

输出:

2100000000
9000000000
3.14
3.14159
A
1

类型速查表:

类型 装什么 大致范围 输入输出格式符
int 整数 约 ±21 亿 %d
long long 大整数 约 ±9.2×10¹⁸ %lld
float 小数 7 位有效数字 %f
double 小数 15 位有效数字 %lf / %f
char 单个字符 一个字节 %c
bool 真假 true / false

⚠️ 坑一:cout << flag 打印的是 10,不是 truefalse 和 Python 打印 True/False 不一样。

⚠️ 坑二:double 默认只显示 6 位有效数字。 上面 d 输出的是 3.14159 而不是全部小数——想控制位数要用 cout << fixed << setprecision(2)

📝 实际写题时的选择:整数用 int,超过 21 亿用 long long,小数一律用 double(别用 float)。

3.7 注释与调试

考纲原文(13): 理解程序的注释和调试的概念。

注释:写给人看的说明,编译器完全忽略。

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

int main() {
    // 这是单行注释,从 // 到行尾都被忽略

    /* 这是多行注释
       中间可以随便换行
       直到遇见结束符号为止 */

    int n = 10;    // 也可以写在代码后面
    cout << n << endl;
    return 0;
}

调试:让程序停下来或者把中间值打出来,看看它到底在干什么。

最实用的一招是打印中间变量

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

int main() {
    int sum = 0;
    for (int i = 1; i <= 5; i++) {
        sum = sum + i;
        cout << "[debug] i=" << i << " sum=" << sum << endl;    // 临时,交卷前删掉
    }
    cout << sum << endl;
    return 0;
}

输出:

[debug] i=1 sum=1
[debug] i=2 sum=3
[debug] i=3 sum=6
[debug] i=4 sum=10
[debug] i=5 sum=15
15

⚠️ 调试输出一定要加个显眼的前缀(比如 [debug]),提交前全部删掉。 忘删 = 输出多了内容 = 0 分。

📝 考试考的是概念:注释不参与编译、不影响运行速度;调试是找出并改正错误的过程。


四、计算机基础常识速记表

考纲原文(1): 了解计算机的基本构成(CPU,内存,I/O 设备等),了解 Windows、Linux 等操作系统基本概念和常见操作,了解计算机的历史及在现代社会中的常见应用。

⚠️ 这一节不写代码,全是选择判断题。背下来就是分。

4.1 计算机的硬件组成

冯·诺依曼结构的五大部件

部件 作用 举例
运算器 做加减乘除和逻辑判断 在 CPU 里
控制器 指挥其他部件干活 在 CPU 里
存储器 存数据和程序 内存、硬盘
输入设备 把信息送进计算机 键盘、鼠标、扫描仪
输出设备 把结果送出来 显示器、打印机、音箱

📝 运算器 + 控制器 = CPU(中央处理器),是计算机的"大脑"。

4.2 存储器

内存(RAM) 外存(硬盘/U盘)
速度
容量
断电后 数据消失 数据保留
别名 主存 辅存

存储单位换算:

1 字节(Byte) = 8 位(bit)
1 KB = 1024 B
1 MB = 1024 KB
1 GB = 1024 MB
1 TB = 1024 GB

⚠️ 进率是 1024,不是 1000。 这是必考点。

4.3 软件

类别 说明 举例
系统软件 管理计算机自身 Windows、Linux、macOS、Android
应用软件 帮人干具体的事 浏览器、Office、Dev-C++、微信

📝 操作系统(OS)是最重要的系统软件,负责管理硬件、文件、进程,是其他软件运行的基础。

常见操作系统: Windows(微软)、Linux(开源、免费)、macOS(苹果)、Android(手机)、iOS(苹果手机)。

4.4 计算机发展历程

时间 核心元件
第一代 1946–1958 电子管
第二代 1958–1964 晶体管
第三代 1964–1970 中小规模集成电路
第四代 1970 至今 大规模/超大规模集成电路

📝 必记:世界上第一台电子计算机叫 ENIAC,1946 年诞生于美国宾夕法尼亚大学。

📝 冯·诺依曼提出「存储程序」思想——把程序和数据一起存进存储器,这是现代计算机的基础。他被称为"现代计算机之父"。


五、单选与判断练习

先做完再对答案。 答案和解析紧跟在题目后面。

5.1 单选题(每题 2 分)

1. 下列哪个不是合法的 C++ 标识符?  A. _count B. sum2 C. 2sum D. maxValue

2. 执行 int a = 5; int b = a++; 之后,a 和 b 的值分别是:  A. 5, 5 B. 6, 5 C. 5, 6 D. 6, 6

3. 在 C++ 中,7 / 2 的结果是:  A. 3.5 B. 3 C. 4 D. 编译错误

4. 下列关于 switch 的说法,正确的是:  A. case 后面可以跟变量  B. 每个 case 后面必须写 break  C. 漏写 break 会继续执行下一个 case 里的语句  D. switch 括号里可以放小数

5. do-while 循环的循环体最少执行:  A. 0 次 B. 1 次 C. 2 次 D. 不确定

6. 下列哪个是 C++ 的关键字?  A. main B. cin C. const D. endl

7. 1 MB 等于多少 KB?  A. 1000 B. 1024 C. 100 D. 8

8. scanf("%d", &n); 中的 & 的作用是:  A. 逻辑与运算  B. 取变量 n 的地址,告诉 scanf 把数据放到哪里  C. 可有可无  D. 表示 n 是整数

9. 世界上第一台电子计算机的名称是:  A. IBM-PC B. ENIAC C. UNIVAC D. Apple I

10. 执行 bool flag = true; cout << flag; 会输出:  A. true B. True C. 1 D. 编译错误

答案与解析:

答案 解析
1 C 标识符不能以数字开头。A 的下划线开头是合法的
2 B 后置 ++ 先把旧值 5 给 b,然后 a 才变 6
3 B 两个 int 相除是整除,小数部分直接砍掉,不是四舍五入
4 C A 错(case 只能跟常量);B 错(可省,但会穿透);D 错(只能整数或字符)
5 B do-while 先执行后判断,所以至少一次
6 C main 是函数名,cin/endl 是标准库里的名字,都不是关键字
7 B 存储单位进率是 1024
8 B scanf 要往变量里写数据,必须知道地址
9 B ENIAC,1946 年,美国宾夕法尼亚大学
10 C cout 输出 bool 打印 1 或 0,不是 true/false

5.2 判断题(每题 2 分,对的打 √,错的打 ×)

1. C++ 中 Sumsum 是同一个变量。( )

2. if 语句后面如果只有一条语句,可以不写大括号。( )

3. for 循环的循环体一定至少执行一次。( )

4. 注释会被编译进最终的程序,所以注释太多会让程序变慢。( )

5. 0 < x < 10 在 C++ 中可以正确判断 x 是否在 0 到 10 之间。( )

6. do { ... } while (条件) 的结尾必须加分号。( )

7. 内存(RAM)里的数据在断电后会丢失。( )

8. printf 输出变量时也需要在变量名前加 &。( )

答案与解析:

答案 解析
1 × C++ 区分大小写,是两个不同的变量
2 语法上允许。但强烈建议永远写大括号,否则容易掉进"漏大括号"的坑
3 × for 是先判断后执行,条件一开始就不成立就一次都不执行。至少一次的是 do-while
4 × 注释在编译时被完全忽略,不进入可执行程序,不影响速度
5 × C++ 会先算 0 < x 得到 0 或 1,再拿它和 10 比,结果恒为真。必须写 x > 0 && x < 10
6 do-while 是唯一结尾要写分号的循环
7 RAM 是易失性存储器;硬盘、U 盘断电后数据保留
8 × printf 只是读出来打印,不需要 &scanf 要往里写,才需要

六、编程练习

先自己写,写完再看参考代码。 参考代码里每一行都有注释,看的时候重点看为什么这么写,不是抄。

题 1 ⭐ 阶梯电费

某地电费按阶梯计价:用电量不超过 100 度,每度 0.5 元;超过 100 度不超过 200 度的部分,每度 0.6 元;超过 200 度的部分,每度 0.8 元。 输入一个整数 n(0 ≤ n ≤ 10000)表示用电量,输出电费,保留 2 位小数。 样例:输入 150,输出 80.00 (前 100 度 = 50 元,后 50 度 = 30 元,共 80 元)

参考代码:

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

int main() {
    int n;
    cin >> n;

    double fee = 0;              // 电费会有小数,必须用 double,且要清零

    if (n <= 100) {
        fee = n * 0.5;           // 全部按第一档算
    } else if (n <= 200) {
        fee = 100 * 0.5          // 前 100 度按第一档
            + (n - 100) * 0.6;   // 超出的部分按第二档
    } else {
        fee = 100 * 0.5          // 第一档满额
            + 100 * 0.6          // 第二档满额
            + (n - 200) * 0.8;   // 剩下的按第三档
    }

    cout << fixed << setprecision(2) << fee << endl;   // 保留 2 位小数
    return 0;
}

要点:

  1. else if 链必须从小到大排(或者从大到小),顺序乱了会走错分支
  2. fee 必须是 doublen * 0.5 里 0.5 是小数,结果是小数,用 int 接会砍掉小数部分
  3. fixed 不能漏:只写 setprecision(2) 输出的是"2 位有效数字"(80 会变成 8e+01),加上 fixed 才是"小数点后 2 位"
  4. 分档计费要"分段累加",不是"整体按一个价"——150 度不是 150 * 0.6

题 2 ⭐⭐ 成绩等级(用 switch 写)

输入一个整数分数 score(0 ≤ score ≤ 100),输出等级: 90~100 输出 A,80~89 输出 B,70~79 输出 C,60~69 输出 D,60 以下输出 E要求用 switch 实现。 样例:输入 85,输出 B

参考代码:

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

int main() {
    int score;
    cin >> score;

    // switch 的 case 只能是具体的值,不能是范围。
    // 所以先除以 10,把 0~100 这 101 个值压成 0~10 这 11 个值。
    // 85 / 10 = 8,92 / 10 = 9,100 / 10 = 10
    switch (score / 10) {
        case 10:                 // 100 分
        case 9:                  // 90~99 分,和 100 分走同一段代码
            cout << "A" << endl;
            break;
        case 8:
            cout << "B" << endl;
            break;
        case 7:
            cout << "C" << endl;
            break;
        case 6:
            cout << "D" << endl;
            break;
        default:                 // 0~5,也就是 59 分及以下
            cout << "E" << endl;
            break;
    }
    return 0;
}

要点:

  1. score / 10 是把范围变成具体值的关键一招——整数除法自动向下取整,正好把每 10 分归成一类
  2. case 10case 9 挨着写:两个入口共用下面同一段代码,这是 case 穿透特性唯一被正当利用的场合
  3. 每段结束都写 break:漏一个就会往下穿透,输出多行
  4. default 兜住剩下的所有情况,比写 case 5: case 4: ... case 0: 干净得多

⚠️ 自测边界:输入 100908960590 各试一遍。 只试 85 是不够的——分档题的 bug 全藏在档位交界处。

题 3 ⭐⭐⭐ 数字拆解(用 do-while 写)

输入一个非负整数 n(0 ≤ n ≤ 2000000000),输出它的位数各位数字之和,中间用一个空格隔开。 要求用 do-while 实现。 样例:输入 375,输出 3 15(3 位数,3+7+5=15) 样例:输入 0,输出 1 0(0 是一位数,数字和为 0)

参考代码:

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

int main() {
    long long n;             // n 可达 20 亿,超过 int 的 21 亿上限太近,用 long long 稳妥
    cin >> n;

    int cnt = 0;             // 位数
    int sum = 0;             // 各位数字之和
                             // 两个都必须清零

    do {                     // 用 do-while:先做一次,保证 n=0 时也能算成 1 位
        sum = sum + n % 10;  // % 10 取出最右边一位
        n = n / 10;          // / 10 砍掉最右边一位
        cnt++;               // 位数 +1
    } while (n > 0);         // ⚠️ 别忘了这个分号

    cout << cnt << " " << sum << endl;
    return 0;
}

要点:

  1. n % 10 取末位、n / 10 去末位——这一对是所有"逐位处理"题目的固定套路,务必记住
  2. 两句的顺序不能反:必须先取末位加进 sum,再砍掉。反过来就丢了一位
  3. 为什么必须 do-while:n = 0 时 while (n > 0) 一次都不进循环,会输出 0 0,但 0 是一位数,正确答案是 1 0do-while 先执行一次,边界天然正确
  4. cntsum 都要初始化为 0:C++ 的局部变量不会自动清零

📝 把这题的 do-while 改成 while 试一遍,输入 0 看看输出什么。 亲眼看见 0 0,你就永远记住这两种循环的区别了。


七、考前自查清单

考前一天,逐条打勾。答不上来的回去翻对应小节。

语法部分:

常识部分:

考场习惯:

⚠️ 最后一句:这本手册能让你看懂,但看懂不等于会写。第六节那三道题,合上手册重写一遍,写得出来才算过。