C++ 进阶 — 第 8 课
| 课程 | 核心 | 一句话记忆点 |
|---|---|---|
| 0003 变量/分支/函数 | if/else、函数 | 函数是「给一段代码起个名字」 |
| 0004 循环/数组 | for、数组 | 重复做 + 按下标取 |
| 0005 string/vector | 动态数组 | push_back 随便加,不用管长度 |
| 0006 嵌套循环 | 双重 for | 外层走一步,内层走一圈 |
| 0007 指针/引用 | & 和 * | 引用是别名,指针是地址 |
| 0008 STL | sort/set/map | 别人写好的武器库 |
| 0009 struct/class | 打包 | 数据和函数装进一个盒子 |
| 0010 递归 | 自己调自己 | 必须有出口,否则爆栈 |
| 0011 栈/队列/优先队列 | stack/queue/pq | 后进先出 / 先进先出 / 自动排序 |
| 0012 复杂度 | 大 O | 估一估程序跑多快 |
| 0013 构造/析构 | 出生和临终 | 构造初始化,析构清理 |
| 0014 文件读写 | ofstream/ifstream | 数据存下来,下次还能用 |
这张表从下往上看,就是项目里代码的执行顺序:先读文件(0014)→ 用 struct 打包(0009)→ 存进 vector(0005)→ 循环算总分(0004)→ sort 排序(0008)→ 写回文件(0014)。
先别看代码,能不能答出来?
vector<int> a(10) 和 vector<int> a{10} 有什么区别?sort 从小到大怎么写?自定义排序函数返回 true 表示什么?map 遍历输出是按什么顺序?while (in >> x) 什么时候停下来?a(10):10 个 0;a{10}:1 个元素,值是 10sort(a.begin(), a.end()) 默认升序;比较函数返回 true = a 排在 b 前面Student s(...)vector<int> a(10) 是 10 个 0,a{10} 是 1 个 10。写法只差一个符号,结果差很远。return true 的意思是「a 排在 b 前面」,不是「a 比 b 大」。想不通就先想「谁应该出现在前面」。return 缺一不可,只写一行会让同分的人顺序乱掉。if (!in) 没写,文件打不开时你会读到一个空 vector,后面 v[0] 直接越界。out << ... 别漏。数据文件 students.txt(每行:姓名 语文 数学 英语):
Alice 95 87 92
Bob 78 90 85
Cindy 88 94 91
David 92 76 88
Eva 85 82 79
要求
名次 姓名 总分 写入 result.txt知识点对照:struct 打包(0009)→ vector 存储(0005)→ ifstream 读 / ofstream 写(0014)→ sort + 比较函数(0008)→ 循环累加(0004)
写之前想三步
进阶挑战(可选)
while 里打印一行,确认读到的名字和三科都对得上。v 排序前后各打印一遍,看是谁的位置错了。result.txt 打开看了吗?名次是不是从 1 开始、总和是不是五个人。students.txt、代码、result.txt 一起贴过来。#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
struct Student {
string name;
int ch, ma, en;
int total;
};
bool cmp(const Student& a, const Student& b) {
if (a.total != b.total) return a.total > b.total; // 总分高的在前
return a.name < b.name; // 同分按名字升序
}
int main() {
ifstream in("students.txt");
if (!in) { cerr << "打不开 students.txt" << endl; return 1; }
vector<Student> v;
Student s;
while (in >> s.name >> s.ch >> s.ma >> s.en) {
s.total = s.ch + s.ma + s.en;
v.push_back(s);
}
if (v.empty()) { cerr << "没有数据" << endl; return 1; }
sort(v.begin(), v.end(), cmp);
ofstream out("result.txt");
for (int i = 0; i < v.size(); i++) {
out << i + 1 << " " << v[i].name << " " << v[i].total << endl;
}
cout << "已写入 result.txt" << endl;
return 0;
}
预期 result.txt:
1 Alice 274
2 Cindy 273
3 David 256
4 Bob 253
5 Eva 246
对一下数字:Alice 95+87+92=274,Cindy 88+94+91=273 —— 前两名只差 1 分,所以「同分按名字」那条规则在这份数据里其实用不上,但换个文件就可能用上,仍然要写。
class 不再只是「打包数据」,而是用 private / public 控制谁能碰、谁不能碰。