C++ 竞赛教程
结构体允许把不同类型的相关数据组合成一个整体,比如把学生的姓名、年龄、分数打包在一起,是竞赛中组织复杂数据的核心工具。
10.1
结构体用 struct 关键字定义,把多个不同类型的数据字段打包成一种新的数据类型。定义好后可以像 int、double 一样使用它来创建变量。
; 必须写!这是初学者最容易遗漏的地方,缺少分号会导致编译错误,且错误提示通常很难看懂。main() 之前,以便全局使用。Point、图的边 Edge、学生信息 Student 等。10.2
定义好结构体后,可以像普通类型一样创建结构体变量,通过 .(点运算符)访问其成员。
| 1 | // 方式1:先定义,再逐成员赋值 |
| 2 | Student s1; |
| 3 | s1.name = "小明"; // 用 . 访问成员 |
| 4 | s1.age = 15; |
| 5 | s1.score = 92.5; |
| 6 | |
| 7 | cout << "姓名:" << s1.name << endl; |
| 8 | cout << "成绩:" << s1.score << endl; |
| 9 | |
| 10 | // 方式2:初始化时直接赋值(按成员定义顺序) |
| 11 | Student s2 = {"小红", 14, 95.0}; // 顺序要与定义一致 |
10.3
可以用结构体数组存储多个同类型数据,每个元素都是一个完整的结构体变量,用 [i].成员名 访问。
| 1 | // 静态数组 |
| 2 | Student students[3] = |
| 3 | { |
| 4 | {"小明", 15, 92.5}, |
| 5 | {"小红", 14, 95.0}, |
| 6 | {"小华", 16, 88.0} |
| 7 | }; |
| 8 | |
| 9 | // 遍历结构体数组 |
| 10 | for (int i = 0; i < 3; i++) |
| 11 | cout << students[i].name << ":" << students[i].score << endl; |
| 12 | |
| 13 | // 结合 vector(动态大小,竞赛中更常用) |
| 14 | vector<Student> stuList; |
| 15 | stuList.push_back({"小明", 15, 92.5}); |
| 16 | stuList.push_back({"小红", 14, 95.0}); |
| 17 | |
| 18 | for (auto &s : stuList) // 范围 for 循环 + 引用 |
| 19 | cout << s.name << " " << s.score << endl; |
10.4
结构体可以作为函数参数传递,同样分为值传递和引用传递两种方式。由于结构体往往包含多个字段,引用传递更为推荐,可避免昂贵的拷贝开销。
const。| 1 | // 值传递:函数内修改不影响原结构体 |
| 2 | void PrintStudent(Student s) |
| 3 | { |
| 4 | cout << s.name << " " << s.score << endl; |
| 5 | } |
| 6 | |
| 7 | // 引用传递:直接修改原结构体(推荐) |
| 8 | void UpdateScore(Student &s, float newScore) |
| 9 | { |
| 10 | s.score = newScore; // 直接修改原结构体 |
| 11 | } |
| 12 | |
| 13 | int main() |
| 14 | { |
| 15 | Student s = {"小明", 15, 90.0}; |
| 16 | PrintStudent(s); // 输出:小明 90 |
| 17 | UpdateScore(s, 95.0); // 修改成绩 |
| 18 | PrintStudent(s); // 输出:小明 95 |
| 19 | } |
| 使用场景 | 推荐方式 |
|---|---|
| 只需读取结构体内容 | const 引用(const Student &s),避免拷贝开销 |
| 需要修改结构体内容 | 普通引用(Student &s) |
| 结构体很小(只有两三个基本类型字段) | 值传递也可以,开销可忽略 |
10.5
竞赛中,结构体最常用的场景之一就是配合 sort() 进行自定义排序。需要提供一个比较函数 Cmp,告诉 sort 按什么规则排序。
| 1 | #include <algorithm> |
| 2 | #include <vector> |
| 3 | |
| 4 | struct Student { string name; int age; float score; }; |
| 5 | |
| 6 | // 自定义比较函数:成绩高的排前面 |
| 7 | bool Cmp(const Student &a, const Student &b) |
| 8 | { return a.score > b.score; } |
| 9 | |
| 10 | int main() |
| 11 | { |
| 12 | vector<Student> v = |
| 13 | { {"小明",15,92.5}, {"小红",14,95.0}, {"小华",16,88.0} }; |
| 14 | |
| 15 | sort(v.begin(), v.end(), Cmp); // 传入比较函数 |
| 16 | |
| 17 | for (auto &s : v) |
| 18 | cout << s.name << ":" << s.score << endl; |
| 19 | // 输出:小红:95 小明:92.5 小华:88 |
| 20 | } |
return a.score > b.score → 成绩大的在前 → 降序return a.score < b.score → 成绩小的在前 → 升序return a.score != b.score ? a.score > b.score : a.name < b.name(成绩不同按成绩降序,相同按姓名升序)