本章目标:跑通你的第一个 C++ 程序;看懂一个程序是怎么从源码变成可执行文件的;学会读报错、用编译选项。
1.1 第一个程序
先别管理论,把下面这个程序敲出来、编译、跑起来。这是所有 C++ 学习的起点。
心智模型:C++ 为什么看着这么杂
很多人学 C++ 觉得内容杂,是因为它同时背着三个时代:带类的 C(对象与继承)、模板(泛型)、现代特性(lambda、智能指针)。这三层会一直混在一起出现,你现在只需要知道它们存在,以后每学一个语法点,问一句“它是为哪一层服务的”,就不会乱。C++ 的设计哲学叫“零开销抽象”:你写的高级写法,运行时不该比手写底层代码慢。
从源码到可执行文件的四步
一个 .cpp 文件变成能运行的程序,要经过四步:① 预处理:处理 #include、#define,本质是纯文本复制;② 编译:把每个 .cpp 单独翻译成机器码,得到 .o 目标文件;③ 汇编:转成机器码(通常和编译一起完成);④ 链接:把所有目标文件和用到的库拼成可执行文件,这时才检查“某个函数到底有没有被实现”。
第一个程序逐行拆解
下面每一行的作用:#include <iostream> 引入标准输入输出库(尖括号表示去系统目录找);int main() 是程序入口,返回类型必须是 int(和 Java 的 void main 不同);std::cout << 表示把右边的数据送进输出流;<< 是运算符重载(同一个符号在整数运算里是左移,在这里叫插入运算符);std::endl 是换行并刷新缓冲区;return 0 表示正常结束(省略也等价于 return 0)。
#include <iostream> // 标准输入输出流
int main() { // 程序入口,返回类型必须是 int
std::cout << "Hello, C++" << std::endl;
return 0; // 正常结束
}
Hello, C++
编译命令:每天都会用的一条
手敲完代码后,在终端(PowerShell)里执行下面的命令编译并运行。这些开关的意思:-std=c++17 用 C++17 标准;-Wall -Wextra 打开大部分警告(C++ 里警告非常重要,很多错误只以警告形式出现);-o hello 指定输出文件名。
g++ -std=c++17 -Wall -Wextra -o hello hello.cpp
.\hello.exe # Windows PowerShell 运行
✍️ 本节练习
写一个程序,第一行输出你的名字,第二行输出“开始学 C++ 啦”,每行都要换行。
输入 无
输出 两行,第一行是你的名字,第二行是“开始学 C++ 啦”。
(本题无输入)小明
开始学 C++ 啦💡 提示 用 std::cout,结尾用 '\n' 换行。
✅ 查看参考答案与解析
#include <iostream>
int main() {
std::cout << "小明" << '\n';
std::cout << "开始学 C++ 啦\n";
return 0;
}
解析 字符串必须用双引号包住;'\n' 是换行字符。
用一条 std::cout 语句输出三个数 1、2、3,要求数字之间用一个空格隔开,最后换行。
输入 无
输出 1 2 3(空格分隔,末尾换行)。
(本题无输入)1 2 3💡 提示 cout 不会自动加空格,需要自己写 ' '。
✅ 查看参考答案与解析
#include <iostream>
int main() {
std::cout << 1 << ' ' << 2 << ' ' << 3 << '\n';
return 0;
}
解析 cout << a << b 输出的是紧挨着的两个值,分隔符要自己加。
1.2 输入输出
输入输出是新手最容易卡住的地方,因为报错往往看不出原因。这一节把最常见的写法直接记住。
cout:流,不是拼接
std::cout 是一个“输出流”对象,<< 把数据一件一件送进去。注意它不会自动加空格、不会自动换行——cout << 1 << 2 输出的是 12,不是 1 2。分隔符要自己写。
cin:读入的两种方式
std::cin >> a >> b 会跳过所有空白字符(空格、换行、制表)再读入;而 std::getline 读一整行(读到换行为止),适合含空格的文字。两者混用有一个经典坑:cin >> n 之后缓冲区里还留着一个换行符,直接 getline 会读到一个空串。
#include <iostream>
#include <string>
int main() {
int n;
std::string line;
std::cin >> n;
std::cin.ignore(); // 吃掉 n 后面遗留的换行符
std::getline(std::cin, line); // 读一整行(可含空格)
std::cout << n << '\n' << line << '\n';
return 0;
}
5
hello world
输入加速两行(算法题必备)
写算法题时在 main 开头加上这两行,cin/cout 会快很多:std::ios::sync_with_stdio(false) 关闭与 C 标准库的同步;std::cin.tie(nullptr) 解除 cin 与 cout 的绑定。另外格式化输出用 <iomanip> 的 fixed 和 setprecision。
#include <iomanip>
#include <iostream>
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
double pi = 3.14159265;
std::cout << std::fixed << std::setprecision(3) << pi << '\n';
return 0;
}
3.142
✍️ 本节练习
读入两个整数 a 和 b,输出 a + b 的结果。
输入 一行两个整数 a b。
输出 一个整数,a 与 b 的和。
3 58💡 提示 std::cin >> a >> b; 一次读两个数。
✅ 查看参考答案与解析
#include <iostream>
int main() {
int a, b;
std::cin >> a >> b;
std::cout << a + b << '\n';
return 0;
}
解析 cin 会自动跳过空格和换行,所以一行读两个数很简单。
先读入一个整数 n,再读入一整行文字(可能含空格),把 n 和这行文字各输出一行。注意:n 后面紧跟的换行不能影响 getline。
输入 第一行整数 n;第二行一行文字(可含空格)。
输出 第一行输出 n,第二行原样输出文字。
5
hello world5
hello world💡 提示 cin >> n 会把换行符留在缓冲区,需要 std::cin.ignore() 吃掉它再 getline。
✅ 查看参考答案与解析
#include <iostream>
#include <string>
int main() {
int n;
std::string line;
std::cin >> n;
std::cin.ignore(); // 吃掉 n 后面遗留的换行符
std::getline(std::cin, line); // 读一整行
std::cout << n << '\n';
std::cout << line << '\n';
return 0;
}
解析 这是 cin 和 getline 混用的经典坑:>> 不消耗换行,ignore() 专门用来丢弃它。
1.3 编译报错与调试习惯
报错信息是学习 C++ 最直接的老师。学会读报错,能省下你 80% 的卡壳时间。
读报错的两个习惯
第一,先看第一条错误,不要看最后一条——后面的错误经常是第一条引发的连锁反应。第二,先看文件名和行号,再看描述。编译器提示的位置有时会偏移一行,比如“缺少分号”往往指的是上一行末尾。
警告就是潜在的错误
C++ 里很多错误只以警告形式出现(比如 if (x = 5) 永远为真、变量未初始化)。打开 -Wall -Wextra 后,见到 warning 就修,不要无视。养成“零警告”的习惯,比什么都值。
手敲,不要复制粘贴
learncpp 和几乎所有优秀教程都强调:示例代码要亲手敲一遍。手敲会让你熟悉常见错误(漏分号、方向写反、括号不配对),也能让你熟悉各种报错信息长什么样。敲完再试着改改数字、改改逻辑,观察输出变化——改代码比抄代码学得快。
✍️ 本节练习
下面这段代码编译不过(有 3 处错误),请手敲一遍,修复后编译运行,让它输出 Hello, C++。
#include <iostream>
int main() {
std::cout >> "Hello, C++" << std::endl // 3 处错误
return 0;
}
输入 无
输出 Hello, C++
(本题无输入)Hello, C++💡 提示 错误藏在:缺头文件、>> 方向、缺分号。
✅ 查看参考答案与解析
#include <iostream>
int main() {
std::cout << "Hello, C++" << std::endl;
return 0;
}
解析 三处错误:1) 缺 #include <iostream>;2) << 方向写反成 >>;3) 缺分号。修复后零错误零警告。
写一个程序输出 Hello, C++,然后用这条命令编译,要求零警告零错误:g++ -std=c++17 -Wall -Wextra -o hello hello.cpp
输入 无
输出 Hello, C++
(本题无输入)Hello, C++💡 提示 -Wall -Wextra 会打开大部分警告;如果看到 warning 就要修。
✅ 查看参考答案与解析
#include <iostream>
int main() {
std::cout << "Hello, C++" << '\n';
return 0;
}
解析 C++ 里很多错误只以警告形式出现,养成零警告编译的习惯。
本章小结
- C++ 程序四步变成可执行文件:预处理 → 编译 → 汇编 → 链接;编译期看声明,链接期看定义。
- cout 不会自动加空格换行;cin 跳过空白、getline 读整行,混用要 cin.ignore()。
- 编译命令 g++ -std=c++17 -Wall -Wextra 要一直开着,警告必须处理。
- 代码亲手敲、报错先读第一条、一次修一个错误。
🧩 本章综合练习
这几道题把本章多个知识点串起来,建议合上资料独立完成,再展开答案对照。
读入一个整数 n(1~5),再读入 n 行文字(每行可能含空格),按格式输出。这道题把第 1 章的三个坑一次踩全:cin 和 getline 混用要 ignore、换行要自己写、输出格式要严格对齐。
输入 第一行一个整数 n;接下来 n 行,每行一段文字(可含空格)。
输出 第 1 行 n=数字;之后 n 行 line i: 内容(i 从 1 开始)。
3
hello world
C++ 新手
第四天n=3
line 1: hello world
line 2: C++ 新手
line 3: 第四天💡 提示 cin >> n 之后缓冲区还留着换行,必须 std::cin.ignore() 再 getline。
✅ 查看参考答案与解析
#include <iostream>
#include <string>
int main() {
int n{};
std::cin >> n;
std::cin.ignore(); // 吃掉 n 后面的换行
std::cout << "n=" << n << '\n';
for (int i = 1; i <= n; ++i) {
std::string line;
std::getline(std::cin, line); // 读一整行,保留空格
std::cout << "line " << i << ": " << line << '\n';
}
return 0;
}
解析 cin >> 跳过空白、getline 读整行,两者混用必须先 ignore。用 '\n' 而不是 endl,大量输出时更快。