FIRST PROGRAM / MACOS + C++20
把一个 .cpp 文件,
编译成能运行的程序。
从打开终端开始,亲手完成保存、编译、运行和重新编译。主线按 Mac 编写;Linux 的编译命令相同,工具安装方式按系统处理。
第一次约 20–30 分钟,计入首个基础单元的动手时间。还不需要 CMake、LLVM IR 或加速卡;手机可以阅读,实际输入命令需要电脑终端。
已有 first.cpp?最短操作是这两步
本页的四个编译诊断选项已统一到新04的选项说明;第一次使用这些选项,先读该小节,再回到本页操作。
先在终端进入 first.cpp 所在目录,再输入下面这行。文件若叫 main.cpp,把输入名换成它即可。
clang++ -std=c++20 -Wall -Wextra first.cpp -o first && ./firstfirst.cpp 是输入源码;-o first 把输出程序命名为 first;./first 表示运行当前目录中的这个程序;&& 表示前面的编译成功后才运行。
1. 打开终端,确认编译器
- 在 Mac 按 Command + 空格,搜索 Terminal / 终端并打开。
- 看到可输入文字的提示符后,输入下面命令并按回车。网页中的命令写在终端,不写进 C++ 文件;也不用复制提示符
$、%或包住代码的三反引号。
clang++ --version能看到 Clang 的版本文字就继续。版本号不需要与教材机器完全一致,但必须支持 C++20。本教程的编译操作已用 Apple Clang 17 在 Mac 上执行。
Mac 没有编译器,怎样准备?
输入下面命令,按系统弹窗完成 Command Line Tools 安装。下载完成后重新运行 clang++ --version,能显示版本再继续;等待安装的时间另计。已有工具时不必重复安装,也不用先下载完整 Xcode。
xcode-select --install这是供你在需要时操作的安装入口;编写本教程时使用已有工具,没有重新安装或更改系统。
Linux 或 Windows 怎么办?
Linux 已有支持 C++20 的 Clang 时,下面命令同样适用;没有时按发行版的官方软件包说明安装 Clang。已有 GCC 时,可把示例的 clang++ 换成支持 C++20 的 g++,仍需实际检查输出。本轮只验证了 Mac/Clang 路径。
Windows 的 PowerShell/MSVC 使用不同的工具与运行写法;已有 WSL 环境可按 Linux 路径操作。不要直接把 macOS 的安装命令粘贴到 Windows。
2. 创建目录,把代码保存为 first.cpp
在终端逐行输入,每行回车:
mkdir -p "$HOME/cpp-practice"
cd "$HOME/cpp-practice"
pwdmkdir -p 创建练习目录(已存在则继续使用);cd 切换终端的当前目录;pwd 显示当前位置。$HOME 是你的个人主目录。路径有空格时要加引号,例如 cd "$HOME/My Cpp Practice"。进入目录只改变终端位置,不会移动文件。
先运行 ls 检查目录。若已经有 first.cpp 或 first,保留旧练习,先创建并进入一个新的练习目录,例如 cpp-practice-2;后续所有 cd 都使用你实际选择的路径。源码与程序仍统一命名为 first.cpp 和 first。接着打开终端编辑器:
nano first.cpp把下面这段完整程序输入或粘贴进去。不要覆盖以前练习的内容。
#include <iostream>
int main() {
int count{2};
count = count + 1;
std::cout << count << '\n';
return 0;
}- 按 Control + O(字母 O)保存,再按回车确认文件名。
- 按 Control + X 退出编辑器,回到终端。这里用的是 Control,不是 Command。
- 输入
ls;文件列表应包含first.cpp。只复制代码到剪贴板,还不等于保存了文件。
若用已有的图形编辑器,保存为这个目录里的纯文本 first.cpp。避免 first.cpp.txt、富文本和弯引号。没有 nano 时也可用这种方式。
3. 编译,然后运行
先生成程序
从这个小节直接开始时,先读命令中编译诊断选项的用途,再执行:
clang++ -std=c++20 -Wall -Wextra first.cpp -o first编译成功通常没有输出,只会回到提示符。输入 ls,现在应能看到源码 first.cpp 和程序 first。出现 error 时先修正,不继续运行目录里可能残留的旧程序。
| 这一段 | 意思 |
|---|---|
clang++ | 调用 C++ 编译驱动;这条命令会完成编译和链接。 |
-std=c++20 | 使用 C++20 语言标准。 |
-Wall -Wextra | 用途见本节命令前的选项说明入口。 |
first.cpp | 要读取的源文件,必须与实际保存的名字一致。 |
-o first | 指定输出文件名;是字母 o,不是数字 0。 |
再启动程序
先预测 2 + 1 会输出什么,再输入:
./first终端应显示:
3
. 表示当前目录,所以 ./first 明确指出程序的位置。单独输入 first,终端通常只会到 PATH 中找命令;输入 ./first.cpp 也不会编译 C++。
没有写 -o、或者想看退出码呢?
Clang 在这里省略 -o 通常会生成 a.out,对应运行 ./a.out。使用明确名字更容易找到程序。
运行结束后紧接着输入 echo $?,显示的是刚才命令的退出码。这里应为 0,来自 return 0;;输出的数字 3 与退出码 0 是两件事。不要在检查退出码前先执行别的命令。
改源码、编译、运行,是三个不同动作
编辑器把文字保存到 first.cpp;此时还没有生成程序。
clang++ 读取 first.cpp,编译并链接,-o first 指定输出文件名。成功通常没有文字输出。
./first 启动当前目录的程序;它执行加一并输出 3。运行时不会重新读取 C++ 源码。
将 first.cpp 的初值改为 5 并保存。若没有重新编译,./first 仍运行旧程序,输出 3。
再次执行编译命令,成功后运行,新程序才输出 6。&& 可以阻止编译失败后继续运行旧程序。
阅读完整推演文字
- 1. 保存源码
first.cpp · 源码:count 初值 2;first · 可执行程序:尚未生成
编辑器把文字保存到 first.cpp;此时还没有生成程序。
- 2. 编译并链接
first.cpp:count 初值 2;clang++:编译 + 链接;first:新程序
clang++ 读取 first.cpp,编译并链接,-o first 指定输出文件名。成功通常没有文字输出。
- 3. 运行程序
./first:启动程序;终端输出:3
./first 启动当前目录的程序;它执行加一并输出 3。运行时不会重新读取 C++ 源码。
- 4. 只改源码,程序没有更新
first.cpp:初值已改为 5;first:仍是旧程序;./first 输出:仍为 3
将 first.cpp 的初值改为 5 并保存。若没有重新编译,./first 仍运行旧程序,输出 3。
- 5. 重新编译,再运行
first.cpp:初值 5;重新编译:生成新 first;./first 输出:6
再次执行编译命令,成功后运行,新程序才输出 6。&& 可以阻止编译失败后继续运行旧程序。
4. 改一行,亲眼看见“重新编译”
- 再次执行
nano first.cpp,把int count{2};改成int count{5};,保存并退出。 - 先直接执行
./first。它仍应输出 3:你只改了源码,旧程序还在。 - 再执行下面这行,编译成功后会运行新程序:
clang++ -std=c++20 -Wall -Wextra first.cpp -o first && ./first这次应输出 6。以后每次改完代码,先保存,再重新编译;网页的“复制代码”按钮只复制文字。
5. 下载的源码怎么运行?
下载第01章的 copy.cpp →点击下载后,先确认浏览器把文件存到了哪里。若位于 Downloads 目录,可以执行:
cd "$HOME/Downloads"
ls确认列表里有 copy.cpp。浏览器若存成 copy (1).cpp,在自己的练习副本中改成便于输入的名字,或在命令中给完整文件名加引号。
clang++ -std=c++20 copy.cpp -o copy && ./copy这里输入名是 copy.cpp,输出名是 copy,所以运行 ./copy。先预测,再对照第01章的复制与状态例子。其他单文件示例使用对应下载文件;多文件程序与厂商 SDK 按所属章节的完整命令运行。
6. 报错先从哪一条看?
no such file or directory / no input files
终端没有找到你写在命令中的源码。
先运行 pwd 和 ls;检查当前目录、大小写及 first.cpp 是否误存为 first.cpp.txt。不要把示例名当作自己实际的文件名。
command not found: clang++ / developer tools 提示
编译器未准备好,或命令写错。
macOS 按下方工具准备步骤检查;Linux 核对自己的 Clang 安装。不要把 g++、clang 和 clang++ 的名字随意混用。
expected ';' / use of undeclared identifier
C++ 源码有语法或名字错误。
先看第一条 error 的文件名、行号、列号;核对上一行的分号和变量拼写。修正、保存后重新编译。后续错误可能只是第一条引起的。
Undefined symbols / undefined reference / missing main
链接阶段找不到需要的定义。
确认文件有 int main(),且不是从函数中间开始复制的片段。多文件程序要一起编译实际需要的 .cpp;不能只把头文件当完整实现。
./first: no such file or directory / permission denied
没有可运行的该文件,或正在尝试运行源码。
先检查编译是否成功、-o 后的名字及当前目录。运行 ./first;first.cpp 是文字,不要用 chmod 来把它“变成程序”。
修改后输出没有变化
运行了旧程序,或改的是另一个目录的文件。
保存编辑器内容,用 pwd、ls 确认位置,重新编译;随后运行与 -o 名字一致的程序。使用本页的 && 命令连接。
需要求助时,提供实际文件名、pwd、编译命令、第一条完整错误和附近几行源码;不要只提供最后一句“编译失败”。
完成后再回到 C++ 内容
现在应能独立做到:找到源文件、编译出指定名字的程序、运行它、修改后重新编译,并解释 3 为什么变成 6。编译成功只说明构建完成,程序是否正确还要对照输入和预期。
后面学调试时用的两种构建
如果刚才去了 Downloads,先切回 first.cpp 所在目录。下面以默认练习目录为例;若前面用了新目录名,把路径一起换成自己的。
Debug:保留调试信息
cd "$HOME/cpp-practice" && clang++ -std=c++20 -Wall -Wextra -g -O0 first.cpp -o first-debug && ./first-debug-g 生成调试信息,-O0 关闭优化;后面的 LLDB 课程会使用。
ASan / UBSan:运行时检查
cd "$HOME/cpp-practice" && clang++ -std=c++20 -g -O1 -fsanitize=address,undefined -fno-omit-frame-pointer first.cpp -o first-sanitize && ./first-sanitize这些动态检查只覆盖实际执行的路径,不能替代测试。没有报错时,程序仍输出它自己的结果。
资料与验证范围
本页源码与第 01 章、下载文件共用同一教学文件;编译、重新编译及故障实验在现有 Mac/Clang 上检查。工具安装入口、其他操作系统与厂商 SDK 不属于这些运行结果。