Chapter 1:Getting Started with C++
对齐第6版 Chapter 1:理解 C++ 起源、过程式与面向对象范式、标准与可移植性,并建立源文件到编译、链接和运行的可重复工作流。
学习目标
- 能解释 C++ 从 C 扩展而来的历史动机,并比较过程式、面向对象和泛型编程各自组织问题的方式
- 能描述 ANSI/ISO 标准、编译器实现和操作系统环境之间的边界,判断一段程序是否具有可移植证据
- 能复现编辑、预处理、编译、链接和运行五阶段,区分旧产物、编译、链接、运行与逻辑错误
机制总览
Chapter 1:Getting Started with C++:机制路径
- 1
为什么开始学语言要先学证据链
初学者常把“编辑器没有红线”“命令没有报错”或“终端出现一行文字”当成同一件事。它们对应不同阶段:编辑器只展示文本和静态提示,编译器检查当前翻译输入,链接器组合定义,操作系统再加载可执行文件。若不能指出当前运行的是哪个产物,后续所有实验都可能建立在旧二进制上。
- 2
C++ 起源:保留 C 基础并扩展抽象工具
Bjarne Stroustrup 创建 C++ 时保留了 C 的表达式、控制流、函数和直接内存能力,并加入类、继承与多态等对象工具。后来模板支持泛型编程。C++ 因而是多范式语言,不要求所有问题都塞进继承层次。
- 3
标准规定语言,编译器提供实现
ANSI/ISO C++ 标准定义源程序语义和标准库契约,GCC、Clang、MSVC 等编译器实现这些规则。
章级决策实验
Chapter 1:Getting Started with C++:机制与证据
切换《Chapter 1:Getting Started with C++》的三个关键教学阶段,先解释机制,再用运行与失败证据验证结论。
选择推理阶段
当前阶段 · 为什么开始学语言要先学证据链
初学者常把“编辑器没有红线”“命令没有报错”或“终端出现一行文字”当成同一件事。它们对应不同阶段:编辑器只展示文本和静态提示,编译器检查当前翻译输入,链接器组合定义,操作系统再加载可执行文件。若不能指出当前运行的是哪个产物,后续所有实验都可能建立在旧二进制上。
可核验证据
从干净构建开始,以固定输入运行本节示例,再加入一个边界或故障场景验证「为什么开始学语言要先学证据链」的状态变化。
学完《Chapter 1:Getting Started with C++》后,应能从输入和前置条件推导状态变化,并用可重复的构建、运行或边界测试证明结果。
失效—证据矩阵
Chapter 1:Getting Started with C++:失效与核验
为什么开始学语言要先学证据链
典型失效
若只复述「为什么开始学语言要先学证据链」结论而不追踪状态、所有权和失败路径,示例扩展成多文件或多对象程序后就容易偏离预期。
核验证据
从干净构建开始,以固定输入运行本节示例,再加入一个边界或故障场景验证「为什么开始学语言要先学证据链」的状态变化。
C++ 起源:保留 C 基础并扩展抽象工具
典型失效
若只复述「C++ 起源:保留 C 基础并扩展抽象工具」结论而不追踪状态、所有权和失败路径,示例扩展成多文件或多对象程序后就容易偏离预期。
核验证据
从干净构建开始,以固定输入运行本节示例,再加入一个边界或故障场景验证「C++ 起源:保留 C 基础并扩展抽象工具」的状态变化。
标准规定语言,编译器提供实现
典型失效
若只复述「标准规定语言,编译器提供实现」结论而不追踪状态、所有权和失败路径,示例扩展成多文件或多对象程序后就容易偏离预期。
核验证据
从干净构建开始,以固定输入运行本节示例,再加入一个边界或故障场景验证「标准规定语言,编译器提供实现」的状态变化。
为什么开始学语言要先学证据链
初学者常把“编辑器没有红线”“命令没有报错”或“终端出现一行文字”当成同一件事。它们对应不同阶段:编辑器只展示文本和静态提示,编译器检查当前翻译输入,链接器组合定义,操作系统再加载可执行文件。若不能指出当前运行的是哪个产物,后续所有实验都可能建立在旧二进制上。
↡从当前源文件开始,经预处理、编译、链接得到可执行文件,再以固定输入运行并核对结果的可重复证明链。本章先建立这条链,再讨论语言特性。每次修改都写下预测:是否能编译、是否能链接、输出或退出码是什么。实际结果与预测不一致时,先定位阶段,不要同时改多处代码。
C++ 起源:保留 C 基础并扩展抽象工具
Bjarne Stroustrup 创建 C++ 时保留了 C 的表达式、控制流、函数和直接内存能力,并加入类、继承与多态等对象工具。后来模板支持泛型编程。C++ 因而是多范式语言,不要求所有问题都塞进继承层次。
↡以步骤、函数和数据流描述计算过程,重点回答算法按什么顺序完成任务。 ↡用对象封装状态与操作,并借助继承和动态分派组织可替换角色的程序设计方式。过程式与面向对象不是新旧替代关系。数值计算函数可能适合过程式分解;具有长期状态和不变量的账户适合类;一种算法服务多种类型时,泛型编程可能更直接。先识别变化与责任,再选机制。
标准规定语言,编译器提供实现
ANSI/ISO C++ 标准定义源程序语义和标准库契约,GCC、Clang、MSVC 等编译器实现这些规则。-std=c++11 选择语言标准模式,-Wall -Wextra 请求更多诊断;两者都不能证明程序逻辑正确。
c++ -std=c++11 -Wall -Wextra -pedantic hello.cpp -o hello
./hello命令行的价值是显式:输入文件、标准模式、警告和输出路径都可记录。IDE 最终也驱动类似工具链;诊断时应找到实际编译/链接命令,而不是只看“Build failed”。
可移植性来自契约与复测
可移植性不是“在我的电脑上能运行”。标准 C++ 源码减少编译器依赖,但文件路径、终端编码、整数宽度、字节序、动态库和操作系统 API 仍可能不同。程序若依赖特定环境,应把前提写入构建和运行契约。
↡程序在声明的编译器、标准模式和平台集合上保持预期语义,并由重复构建和测试证明的能力。最小可移植实验至少在两套编译器或两种严格模式下构建,保留警告,并使用固定输入比较输出。标准只规定某些类型的最小范围,不保证 int 永远 32 位;路径分隔符和可写目录也不应靠猜测。
创建程序是五个可观察阶段
创建程序的 mechanics 可以拆为源文件、预处理、编译、链接、运行。预处理展开 include 与宏;编译器检查语法和类型并生成目标文件;链接器解析目标文件和库之间的符号;操作系统加载程序并提供参数、环境与 I/O。
↡单个源文件经预处理后形成、由编译器独立处理并生成目标文件的完整输入。#include <iostream>
int main() {
std::cout << "C++ build evidence\n";
return 0;
}main 是托管 C++ 程序入口,返回 0 通常表示成功。#include 在预处理阶段提供声明文本;std::cout 属于标准命名空间。此处先确认阶段与结果,语句和输入输出细节留给 Chapter 2。
编译与链接错误必须分开
若源码缺少右花括号,编译器无法生成目标文件;若 greet() 有声明但实现目标文件未加入命令,调用点可以编译,链接却报告未定义引用。两者的修复证据不同。
// greet.hpp
void greet();
// main.cpp 可以编译,但未链接 greet.cpp 时最终程序无法生成。
int main() {
greet();
}定位时先保留第一条根因诊断,再检查后续消息。大量级联错误往往来自前面一个未闭合 token;链接错误则要核对定义签名、目标文件和最终链接命令。
旧可执行文件会伪造成功
一次构建失败不会自动删除上次成功生成的 hello。若随后直接运行旧文件,终端仍会输出,造成“编译报错但新代码生效”的错觉。删除产物、使用构建目录并让运行依赖成功构建,可以切断这种混淆。
小结
- C++ 在 C 的过程式基础上加入对象和泛型工具,多范式意味着按问题选择组织方式
- ANSI/ISO 标准定义契约,编译器实现契约;标准模式与警告选项应成为构建记录
- 可移植性必须声明平台范围并重复构建测试,不能由单机运行推断
- 源文件依次经过预处理、编译、链接和运行,每个阶段有独立产物与错误
- 旧可执行文件会伪造新代码成功,运行步骤必须依赖当前构建完成
练习
- 问题 1:比较范式。 同一个温度转换程序和带余额不变量的账户,分别适合怎样组织?
- 问题 2:定位阶段。
main.cpp生成了目标文件,但报undefined reference to greet(),为什么不是编译错误?
- 问题 3:证明当前产物。 设计一个实验识别运行的是不是旧可执行文件。
名词解释
名词解释
本章出现的专业名词,用大白话再讲一遍。
- 构建运行证据链
- 从当前源码到预处理、编译、链接、运行和结果核对的可重复证明链。
- 过程式编程
- 以步骤、函数与数据流组织算法的程序设计方式。
- 面向对象编程
- 以封装状态与操作的对象及其关系组织程序的方式。
- 语言标准
- 规定 C++ 语法、语义和标准库接口的版本化契约。
- 可移植性
- 在声明的平台和实现集合中保持语义并有复测证据的能力。
- 翻译单元
- 源文件经预处理后由编译器独立处理的完整输入。