简介:《信息学奥赛一本通·编程启蒙 C++版》1-86课合集以单个PDF形式呈现,面向零基础C++学习者与准备GESP、信息学奥赛的入门选手。内容从第一个C++程序、输入输出、整型与浮点型、字符类型,延伸到多分支if、switch、for/while/do-while循环、程序流程图、循环嵌套、枚举答案,再到时间复杂度与空间复杂度、字符与数学库函数、进制转换、位运算、自定义函数、递归、GDB调试、指针、一维数组、vector、容器迭代器等,形成一条完整的C++启蒙路径。文件共1个pdf,压缩包仅171KB,轻量易存。该资源已被3810人浏览学习。每课均可在哔哩哔哩专栏找到对应配套文章,适合自学对照、课堂补充或赛前系统复习,能帮助读者高效建立编程思维与代码调试能力。 “信息学奥赛一本通·编程启蒙C++版”这个PDF,我最近刚好完整刷过一遍,也拿它带过几个零基础的学生。先说个结论:这本书和很多人印象里的那本“绿皮一本通”完全是两码事,它是一套按“课”划分的零基础C++启蒙教材,1到86课就相当于一整学期的编程入门课。但它本身内容量不小,如果只是从头翻到尾,或者当成题库狂刷,很容易学完就忘。
这篇文章我不打算帮你逐课翻译教材内容,而是想讲点更实在的:这套课该怎么用、环境怎么配最不容易劝退、哪些地方是孩子最容易卡住的点、以及学完之后下一步往哪走。我带学生过程中踩过不少坑,写出来给你避避雷。
1. 这套1-86课到底在教什么:搞清楚定位,才不会白学
1.1 它和“经典一本通”最大的区别是什么
很多家长第一次接触“信息学奥赛一本通”这个系列,是在搜题的时候搜到那本经典的“绿书”——那本质上是题库+算法讲解,默认读者已经有C++语法基础,拿来刷题和备战CSP/NOIP的进阶用书。而这本带有“编程启蒙”和“C++版”字样的教程,定位完全不同:它是从零开始,按课组织,一课一个主题,包含知识点讲解、示例代码、习题三部分,难度坡度比绿书缓和得多。
从目录结构来看,1-86课的编排习惯大致是这样的:前面十几课是头文件、命名空间、变量、cin/cout输入输出这些最基础的东西;中间一大块是if分支、for和while循环、一维数组和二维数组;再往后是函数、结构体、指针的入门;最后十几课会引入排序、查找、简单模拟这类“算法萌芽”。以我个人经验,这套课程非常适合小学高年级到初中低年级、从来没写过代码的孩子上手。如果孩子已经有一定编程基础,这本书的速度会显得略慢,可以直接跳着看。
1.2 为什么“按课学”比“按章节刷”更科学
这本书最明显的特点是“课”这个单位。一节课的量通常控制在一到两个小时能消化完,这比传统教材一上来甩出几十道同类题要友好得多。我带学生的节奏是:先读知识点和示例代码,再把示例代码自己手敲一遍,运行出结果,然后做课后的两三道练习题。这里的核心逻辑是“先模仿,再变通”,而不是“先看书,再闭卷写”。
还有一个容易被忽略的设计:86课的难度并不是一条直线拉升的,它有大量重复和循环。比如for循环可能在好几课里反复出现,但每次都会增加一个新的应用角度。这是典型的螺旋式教学法。但正因如此,如果孩子跳着学、跳着看,会感觉“这个我学过啊”,从而产生虚假的熟练感。我的建议是:老老实实按顺序学,哪怕某课感觉简单,也把示例代码敲一遍,因为敲代码本身练的是手感,不是知识点。
注意:这本书的课后题量其实不算大,如果孩子学完某一课后觉得“吃不饱”,不要硬刷这本书里的题,而是去洛谷或一本通OJ上找对应知识点的入门题补充练习。这本书更适合做“课本”,不适合当“题典”。
2. 环境是第一道坎:Dev C++和VSCode两条路线怎么选
2.1 我的真实结论:启蒙阶段先别急着上VSCode
很多家长一上来就搜“VSCode配置C/C++环境”,觉得用VSCode显得专业。但如果孩子是零基础,我强烈建议启蒙阶段先用Dev C++。原因很简单:Dev C++安装快,绿色免安装版本也有,打开就是编辑器,“编译运行”就一个按钮,所有输出直接在下面弹出来。
用VSCode当然可以,但对零基础孩子来说,配置路径太长:要装MinGW、要配置环境变量、要写tasks.json和launch.json、要理解工作区概念……这一套流程走下来大人都容易头晕,孩子很可能在还没写第一行代码之前就失去了兴趣。VSCode是写给有一定基础、需要更强大调试功能的开发者的,不是写给第一个程序是Hello World的孩子用的。
2.2 如果坚持用VSCode,这套配置可以直接抄
当然,也有家长希望一步到位。下面这套配置我实测过可用,拿给学生也跑通过,你可以直接参考。
第一步,下载安装VSCode,然后在扩展市场里搜索“C/C++”,安装Microsoft官方那个扩展。
第二步,安装编译器。我推荐用MinGW-w64(通过MSYS2安装,或者直接用独立的winlibs发行版)。安装完成后,把编译器bin目录的路径添加到系统环境变量Path里。这一步容易忽略,很多人配置了半天,代码一直报“g++不是内部或外部命令”,就是环境变量没配好。
第三步,在项目文件夹下建好.vscode目录,创建tasks.json,代码如下:
{ "version": "2.0.0", "tasks": [ { "label": "C++ 编译运行", "type": "cppbuild", "command": "g++", "args": [ "-fdiagnostics-color=always", "-g", "${file}", "-o", "${fileDirname}\\${fileBasenameNoExtension}.exe" ], "options": { "cwd": "${fileDirname}" }, "problemMatcher": ["$gcc"], "group": { "kind": "build", "isDefault": true }, "detail": "编译当前文件并生成同名exe" } ] }第四步,创建launch.json,用于断点调试:
{ "version": "0.2.0", "configurations": [ { "name": "C++ 调试", "type": "cppdbg", "request": "launch", "program": "${fileDirname}\\${fileBasenameNoExtension}.exe", "args": [], "stopAtEntry": false, "cwd": "${fileDirname}", "environment": [], "externalConsole": false, "MIMode": "gdb", "miDebuggerPath": "gdb", "preLaunchTask": "C++ 编译运行", "setupCommands": [ { "description": "为 gdb 启用整齐打印", "text": "-enable-pretty-printing", "ignoreFailures": true } ] } ] }这套配置的逻辑是:按F5直接编译并调试当前文件。注意miDebuggerPath写gdb,依赖环境变量,如果调试时提示找不到gdb,就改成gdb.exe的具体绝对路径。
2.3 编译器版本带来的隐性坑
不管用Dev C++还是VSCode,都要留意编译器版本对应的C++标准。Dev C++早期版本自带的老编译器默认支持的是C++98,很多新写法不支持。比如基于范围的for循环(for (int x : arr))、auto关键字,老编译器会直接报错。解决办法是装新版Dev C++(比如带TDM-GCC的5.11改进版),或者在编译器选项里加上-std=c++14。
我实际教学时遇到过孩子照着网上的代码敲,怎么都编译不过,最后发现是编译器标准太低。这个坑很隐蔽,因为报错信息对初学者来说完全看不懂。所以拿到Dev C++的第一件事,我建议在“工具-编译选项”里加上-std=c++14 -O2 -Wall,这样既能用上新语法,-Wall还会把一些不规范的警告显示出来,帮助养成好习惯。
3. 从“看得懂”到“写得出”:语法向算法的第一个堵点转化
3.1 孩子最常在冒泡排序这里“断崖式听不懂”
1-86课进行到后半段,第一个让大量孩子卡住的知识点几乎都是排序,尤其是冒泡排序。很多时候孩子前面学循环、数组都觉得还行,一到冒泡排序就彻底懵了。为什么?因为前面每课都只有一个新知识点,而排序要同时调动“循环嵌套”“数组下标”“交换变量”“边界控制”四样东西。
我带学生的方法是:不直接讲代码,先拿扑克牌或者写着一组数字的纸条,在桌子上模拟排序过程。比如4, 3, 2, 1这四个数:
- 第一轮:比较第1个和第2个(4>3,交换),第2个和第3个(4>2,交换),第3个和第4个(4>1,交换),结果是3, 2, 1, 4。数字4沉到了最右边。
- 第二轮:比较前三个数,结果是2, 1, 3, 4。
- 第三轮:比较前两个数,结果是1, 2, 3, 4。
让孩子亲手动一轮,他就能明白为什么要“n-1轮”,为什么每一轮比较的次数要减1。然后再看代码,很多“凭空看不懂”的地方就通了:
#include <iostream> using namespace std; int main() { int a[5] = {4, 3, 2, 1}; int n = 4; for (int i = 0; i < n - 1; i++) { for (int j = 0; j < n - 1 - i; j++) { if (a[j] > a[j + 1]) { int t = a[j]; a[j] = a[j + 1]; a[j + 1] = t; } } } for (int i = 0; i < n; i++) { cout << a[i] << " "; } return 0; }这段代码里最容易写错的就是内层循环的结束条件n - 1 - i。很多孩子会写成n - 1,结果每一轮都把已排好的最大数再比较一遍——程序不会报错,但逻辑上是低效的。如果写成n - i,则会出现a[j + 1]数组越界,运行结果可能直接崩溃或输出乱码。这种“不报错但结果错”的情况,恰恰是启蒙阶段最有价值的纠错机会。
3.2 从启蒙语法到算法思维之路:排序后面是什么
学完冒泡排序后,我会观察到,能独立把冒泡排序写对的孩子,心智上已经完成了一次“算法思维”的飞跃。这时就可以往前走了。根据大家在热搜里常搜的词,比如“c++二分算法”“快速幂算法c++”“单调栈算法c++”,可以看出来,很多学完启蒙课程的人接下来会往这些方向走。
但这里我要泼一盆冷水:二分、快速幂、单调栈这些,不是启蒙阶段该碰的东西。它们需要的前置知识远不止语法,还有递归理解、复杂度分析、问题转化能力。我的建议路线是:先彻底掌握排序、模拟、枚举这类“暴力算法”,然后学二分思想(因为二分本身依赖“有序”这个条件,学完排序后正好衔接),再往后是贪心、搜索(DFS、BFS)、简单动态规划。
至于结构体链表这类偏数据结构的内容,启蒙课的指针部分只会简单提及。如果孩子对指针感到吃力,可以先跳过,用数组模拟链表的方式理解“怎么穿成一串”,并不会影响后续学习。真正需要会把链表用得滚瓜烂熟,是学到树和图之后的事了。
4. 启蒙阶段最容易踩的四个坑及完整排查链路
4.1 四个高频“不报错但结果不对”的坑
我带学生这段时间,发现有几个错误是几乎所有初学者都会至少踩一次的:
- 变量未初始化就参与计算。C++里局部变量不会自动清零,如果你定义了一个
int sum;就直接用,它的初始值是那块内存里的残留值,程序不会报错,但结果完全不可控。 - 赋值符号
=和判断相等符号==写混。这个太经典了,尤其出现在if条件里,比如写成if (a = 1),程序不报错,但条件永远成立。 - 数组下标从1开始还是从0开始搞混。很多教材里的生活化题目喜欢从1开始说“第1个数”,但C++数组下标从0开始,孩子写着写着就串了。
- 循环里忘记更新循环变量,导致死循环。这个在Dev C++里表现为程序运行后下方的黑色窗口一直在闪,关也关不掉,只能强制结束。
4.2 一个真实的排查案例:冒泡排序结果总是不对
有个学生写的冒泡排序,输入5个数字,排序后输出的结果,第二位和第三位偶尔是错位的。我让他别急着改,用“打印中间值”的方法排查。第一步,在每一轮外层循环结束后,输出当前整个数组的状态。运行后发现第一轮结果正确,第二轮从第三轮开始出现了不该出现的重复数字。第二步,通过打印内容发现,内层循环把已经排好的尾部数字又进行了交换。第三步,检查循环边界,问题就出在他把内层循环写成了j < n - i,当j达到n-1-i后,a[j+1]实际上访问到了已经排好的下一个位置,造成了不可预期的覆盖。把条件改回j < n - 1 - i后,问题消失。
这个案例的普适性在于:它展示了“不猜,去看”的调试思路。对初学者来说,遇到结果不对,不要盯着代码干瞪眼,更不要随手改一个数字碰运气。最简单有效的办法就是在关键位置加cout打印中间值,观察程序在哪个节点开始偏离预期。这个习惯一旦养成,后面学什么都省力。
提示:Dev C++里有断点调试功能,按F4可以插入断点,F8单步执行。但对启蒙阶段的孩子来说,打印法往往更直观。断点调试可以等上初中后再正式训练。
5. 学完1-86课之后:接下来怎么走才是关键
5.1 先别急着重开一本新书,用做题来检验
学完86课,很多人的第一反应是买下一本书继续学。我反而建议先停一停,用一两周时间在洛谷或一本通OJ上找基础题刷一刷。刷哪些?找“入门”“普及-”难度的题目,优先选择那些一看就知道知识点学过、但需要动点脑子的题。
这样做有三个作用:一是检验前面学的语法是不是真的掌握了,很多孩子看书觉得会,一做题就发现连cin怎么循环输入都写不对;二是熟悉在线评测系统(OJ)的输入输出格式要求,这个和本地运行不一样,本地只要结果对就行,OJ要求严格匹配输出格式,多一个空格都可能不给分;三是让孩子体验“提交代码-看评测结果-修改-再提交”这个循环,这种即时反馈带来的成就感,比看书大得多。
5.2 CSP-J初赛是现实的短期目标
如果孩子是小学高年级或初中低年级,学完这套课程后,可以开始准备CSP-J(原NOIP普及组)的初赛。初赛是笔试,里面会考一些纯语法选择题和读程序写结果题。这时候你会发现,启蒙课里那些“当时觉得很简单”的知识点,其实覆盖了初赛语法部分的绝大部分内容。
至于复赛,那就是另一个话题了。复赛要求在一个考场上用记事本式的简陋编辑器写代码,不能依赖Dev C++的调试功能,也不能上网查资料。这其实启发了一个很重要的习惯:平时做练习时,要经常脱离调试工具,只凭肉眼和打印语句来定位错误。启蒙阶段如果能把这种“裸写-自查”的能力练出来,后面复赛会轻松很多。
5.3 更远一点的进阶方向
学完启蒙内容,接下来按顺序会接触到的核心内容大致是:枚举与模拟、二分查找与二分答案、贪心算法、深度优先搜索和广度优先搜索、简单动态规划(背包问题、最长上升子序列等)、栈与队列、树与图的基本遍历。
这些内容在传统“绿皮一本通”里都有成体系的讲解,可以拿那本书作为进阶教材。另外,像“c++八股”“c++多线程”“opencv棋盘格标定”“c++网络编程”这些热搜词对应的是工业开发和视觉方向的领域,和信息学竞赛不是一个赛道。如果你被这些词吸引过去,请先克制住——那属于学会了编程之后再看的东西,启蒙阶段碰它们只会消耗学习热情。认知上清楚“未来可以往这个方向发展”就够了,行动上还是要乖乖把算法基础打牢。
最后分享一点我带孩子的实际操作体会:学编程这件事,“孩子愿意每天摸一下键盘”比“今天学了三个新知识点”重要得多。1-86课这套教材胜在节奏合理,每天一小课,细水长流,比周末突击两小时效果好上不少。如果孩子走到了某课确实困住了,别硬推。换一天再回来,经常就豁然开朗了。这一点,我试过好多次,屡试不爽。
本文还有配套的精品资源,点击获取