跳至内容
Topos Uranos

摘要

本课结束本课程的第一单元,这一单元讲的是用 C++ 编程的第一步。它重建一条概念链:从规格已定的问题出发,经过算法、源代码、编译与链接、可执行文件以及程序与外界的交流,直到按出现时刻分类的错误;它把其中适用于任何语言的内容与 C++ 特有的内容区分开;它汇集本单元展示过的未定义行为,以及由此得出的本课程规则:始终带着警告编译,在开发期间还要带着检测器(sanitizer);它在结业测评中重复入门测评的技能;最后以六道综合整个单元的挑战题结束:用最少的硬币找零、不用循环的对齐表格、一个含有五类五个缺陷的程序、一个关于输出缓冲区的实验、一个格式固定的日期,以及向只懂解释型语言的人解释编译器。

学习目标

  1. 不借助帮助走完从题目到程序运行的全过程:写出规格说明,写出算法,手工执行,用 C++ 写出来,用本课程的选项编译,运行并核对结果。
  2. 说明这一过程的每一步由哪个工具起作用(编辑器、预处理器、编译器、链接器、检测器),以及每个工具接收什么、交出什么。
  3. 根据错误的表现识别其类别(编译错误、链接错误、运行时错误或逻辑错误),并按错误显露的顺序改正多个错误。
  4. 用一个例子说明什么是未定义行为,以及本课程为什么带着警告和检测器编译。
  5. 在本单元所学的内容中,区分适用于任何语言的内容与 C++ 特有的内容。

本单元的收获

本单元的目标是:带领从未编过程序的人,从用日常语言表述的问题出发,走到一个能编译、能运行、能读取数据并写出结果的程序,并且知道一路上每个工具做了什么。它做到了这一点,所依靠的只是导言声明为已知的内容:学校里的算术、按书面指示办事的习惯,以及对文件和文件夹的操作。

从问题到算法

从问题到算法一课确立了:一个问题由它的规格说明确定,这是一份契约,对每个满足前置条件的输入承诺后置条件,对前置条件以外的输入则不作任何承诺。算法是一个有穷、确定、通用的过程,用编号步骤写出,借助跟踪表手工执行,由顺序、选择和重复构成;每个重复都配有一个变式,即一个在每一轮中减小、从而保证重复终止的自然数量。

程序、编译器与 C++

程序、编译器与 C++一课表明,C++ 程序的文本不能原样执行:预处理器、编译器和链接器把它变成可执行文件。由此得出贯穿整个单元的区分:只取决于文本的东西在编译或链接时发现,取决于数据的东西只有在运行时才会发现。这一课比较了编译型模型与解释型模型,并说明了本课程为什么使用 C++23 并用 -std=c++23 来指定它。

安装环境

在 Windows、macOS 和 Linux 上安装环境一课安装了支持 C++23 的编译器,以及带 C++ 扩展的 Visual Studio Code。它在方法上的启示是:编辑器并不编译,而是调用一个终端必须能找到的编译器;消息的确切文字能区分安装故障与调用故障。

编译、运行与配置

编译、运行与配置一课确定了编辑、保存、编译、运行、阅读的工作循环,以及本课程的编译命令。它区分了错误与警告:错误使可执行文件无法生成,警告允许生成,但指出可疑的代码;它启用了监视运行的检测器(内存错误检测器 AddressSanitizer,以及未定义行为检测器 UndefinedBehaviorSanitizer),并展示了它们的局限;它还说明,文件、编译器和控制台必须在 UTF-8 上一致。

程序的解剖

程序的解剖一课剖析了最小程序:声明每项依赖的头文件;作为入口点、其返回值就是退出码的 main;命名空间 std;语句、块和注释。它教人从第一条开始阅读消息,并确定了本课程的风格指南。

输入、输出与错误

输入、输出与错误一课让程序与外界接触:std::println 按格式说明准确写出所要求的内容,std::cin 读取数据,并在第一个不合用的字符处停下。读取时若遇到不能构成数字的字符,就把变量置为零,并让输入流处于错误状态,而且悄无声息(类型容纳不下的数或已经耗尽的输入会在变量中留下别的值,这一课列举了这些情形);因此读取的结果要检查。这一课以按出现时刻给错误分类结束了本单元:编译错误、链接错误、运行时错误和逻辑错误。