结构体
结构体可以看作是一系列元素组合的组合体,也可以理解为是自定义的数据类型,且该类型中可以存储多种数据。
1.定义结构体
一个结构体的定义示例,如下所示:
struct Student {
int value;
double weight;
string name;
}; // 注意这个分号!这里其实也可以定义结构体的变量、数组
Student s1; // 定义了Student类型的一个变量
Student s2[105]; // 定义了Student类型的一个数组
上面定义了一个名为 Student
的结构体,三个成员元素 value, weight, name
,类型分别是 int, double, string
。
后续定义了 Student
类型的变量 s1
和 数组 s2
,其实还可以定义常量、指针等等,普通数据类型可以做到的事,结构体类型也是可以做到的。
对于结构体类型定义出来的变量,可以理解为其一个变量中就记录了多个信息,比如 s1
里面就有三个数据,并且这些数据可以是不同类型的。
另外,一般结构体的类型名,为了区分一般是首字母大写。
2.访问/修改成员元素
可以通过 变量名.成员元素名
来访问指定成员元素,例如在上例中,可以使用 cout << s1.value;
来输出 s1
中的 value
元素,这些元素的使用场景和普通变量一样,只是写法有所不同而已。
结构体数组也是一样的,加上下标即可,下面是简单演示:
#include <bits/stdc++.h>
using namespace std;
struct Student {
int value;
double weight;
string name;
};
Student s1; // 定义了Student类型的一个变量
Student s2[105]; // 定义了Student类型的一个数组
double sum = 0;
int main() {
cin >> s1.value >> s1.weight >> s1.name;
cout << s1.name << " " << s1.weight << '\n';
for (int i=1; i<=10; i++) {
cin >> s2[i].value >> s2[i].weight >> s2[i].name;
sum += s2[i].weight;
}
cout << sum;
return 0;
}
3.结构体的应用场景
其实很多场景不使用结构体一样可以达成相同的效果,只是实现起来有的麻烦有的简单。
结构体的好处是可以把多个不同的元素捆绑在一起,其实这一功能多定义几个数组也可以实现,但用结构体就只需要定义一个数组了,减少了思考的难度。
另外,在后续学习一些算法,例如 排序、广度优先搜索、最短路 等等时,我们可能需要把好几个元素放在一起操作,例如交换、添加、删除等等,使用结构体可以让代码更清晰,避免过多的变量定义。
4.结构体排序
在函数章节我们学习了 sort 的使用,它可以对数组进行排序,那么对于结构体数组该如何进行排序呢?
需要注意的是,结构体是不会自带排序规则的(这个很好理解,一个结构体里常有好几个数据类型,那到底谁说了算呢),所以我们必须自定义排序规则,有两种方式:
1.外部定义比较函数
其实就是给 sort
自定义比较规则,注意 cmp
函数的类型应该是结构体类型即可:
#include <bits/stdc++.h>
using namespace std;
struct Student {
int value;
double weight;
string name;
};
int n;
Student a[1005];
bool cmp(Student a1, Student a2) {
return a1.weight > a2.weight; // 按照 weight 从大到小排序
}
int main() {
cin >> n;
for (int i=1; i<=n; i++) cin >> a[i].name >> a[i].value >> a[i].weight;
sort(a+1, a+1+n, cmp);
for (int i=1; i<=n; i++) cout << a[i].name << " " << a[i].weight << '\n';
return 0;
}
2.重载结构体的比较运算符
这一写法在后面偶尔会用得到,因为后续大量用到 STL
容器,如果把结构体作为容器存储的类型的话,例如堆,那么重载比较运算符会让使用 STL
变得简单。
#include <bits/stdc++.h>
using namespace std;
struct Student {
int value;
double weight;
string name;
// 这样重载,相当于在比较两个结构体变量谁更小时,就是在比较谁的 weight 更小
bool operator < (const Student& other) const {
return weight < other.weight;
}
};
int n;
Student a[1005];
int main() {
cin >> n;
for (int i=1; i<=n; i++) cin >> a[i].name >> a[i].value >> a[i].weight;
sort(a+1, a+1+n);
for (int i=1; i<=n; i++) cout << a[i].name << " " << a[i].weight << '\n';
return 0;
}