目录
结构体的叙述:(下一段选自百度百科)
在C语言中,结构体(struct)指的是一种数据结构,是C语言中聚合数据类型(aggregate data type)的一类。结构体可以被声明为变量、指针或数组等,用以实现较复杂的数据结构。结构体同时也是一些元素的集合,这些元素称为结构体的成员(member),且这些成员可以为不同的类型,成员一般用名字访问。
当然,这些叙述对新手理解来说更加懵逼了。
所以,我们首先要用人话来弄清楚结构体有什么用。
我们已经学过int,doule等数据类型,但是在处理实际问题中,一个单位的信息为一个整体,这个整体里面有会有许多的信息,比如,当要储存一个一名学生的信息,我们暂且称一名学生的所有的信息为一个单位的信息,那么这个单位的信息中可能会包括姓名、学号、成绩、身份证号等等子信息,这时结构体就将这些子信息组合成一个单位信息储存起来,使我们后期处理多位学生信息时更加方便。
接下来我们来了解结构体在C/C++中是如何定义和使用的(由于作者能力有限,这里介绍一些皮毛)
struct 结构体名{
子信息1数据类型 子信息1数据名;
子信息2数据类型 子信息2数据名;
};
eg.
struct student{
char name[100];//将一个学生的姓名存入name数组中
int xuehao;//将一个学生的学号存入变量xuehao中
int chengji://将一个学生的成绩存入变量成绩中
};
上述举例的代码构造的结构体只能存储一个学生的信息,因此我们要通过多个变量或者数组来储存多个学生的信息。
这里介绍4种定义的格式:
//常规定义
struct student{
char name[100];
int xuehao;
int chengji;
};
struct student Jack;
//类比定义int类型数据时,int n这样定义了一个整型n,同理struct student Jack定义了一个Jack的结构体,其中包括了Jack的姓名,学号和成绩;
//我们也可以通过定义struct student Jack,Joy,Mark这样来定义三个学生的结构体;
//因此在实际问题中,我们通常定义一个数组来储存多个学生的信息;
struct student{
char name[100];
int xuehao;
int chengji;
};
struct student a[105]; //以上是常规定义;
//声明的同时定义
struct student{
char name[100];
int xuehao;
int chengji;
}Jack;
//故名思意在定义结构体时同时定义变量名;
//同理,定义数组也可以;
struct student{
char name[100];
int xuehao;
int chengji;
} a[105]; //以上是声明的同时定义
//结构体的嵌套
struct date{
int nian;
int yue;
int ri;
};
struct student{
char name[100];
int xuehao;
int chengji;
struct date birthday;//嵌套struct date;
};
//以上是结构体的嵌套
//匿名结构体
struct{
char name[100];
int xuehao;
int chengji;
}Jack;
//通常匿名结构体会直接声明,比如上面直接定义了Jack,在之后代码中直接用Jack就行了。(这里就不多赘述了,因为作者也不会)
//以上是匿名结构体
了解定义方式后,接下来再学习如何初始化和应用。
//初始化
#include<bits/stdc++.h>
using namespace std;
struct student {
char name[100];
int xuehao;
int chengji;
}Jack;
int main(){
struct student Jack={"Jack",20220226,98};//是不是和数组初始话很像,确实基本没啥区别;
//当然我们也可以这样
//strcpy(Jack.name,"Jack");因为char类型数组中,一个空位只能存储一个字符,所以需要strcpy()函数来存入整个name;
//Jack.xuehao=20220226;
//Jack.chengji=98;
printf(Jack.name);//输出了Jack中的name
printf(Jack.xuehao);//输出了Jack中的xuehao
printf(Jack.,chengji);//输出了Jack中的chengji
return 0;
}
//用数组来定义时
#include<bits/stdc++.h>
using namespace std;
struct student {
char name[100];
int xuehao;
int chengji;
};
struct student a[105];
int main(){
int i;
for(i=0;i<学生位数;i++){
cin>>a[i].name>>a[i].xuehao>>a[i].chengji;//第一次将输入的姓名,学号和成绩存入a[0]中,第
二次将输入的姓名,学号和成绩存入a[1]中......
}
for(i=0;i<学生位数;i++){
cout<<a[i].name<<endl;//依次输出每个name;
}
return 0;
}
另外结构体还有一个重要部分是结构体指针,但因为我还没有学到,所以以后再写吧。
为了更好的初步掌握结构体,这里建议去sdnuoj上去做1104、1268、1028、1012、1093。这几道题的答案将在我接下来的博客中详细。
例题讲解
sdnu.1104
#include <bits/stdc++.h>
using namespace std;
struct gs {
int yh;
int sj;
};
struct gs a[100005];//定义一个gs结构体
bool cmp(gs x, gs y) { //注意这里的书写格式,类比定义函数时 函数名(数据类型 数据名)。
if (x.sj < y.sj) { //注意这里的书写格式,理解下。
return 1;
} else {
return 0;
}
} //按照观察数据从小到大排序
int main() {
int n, m;
int s = 0;
int i;
while (scanf("%d %d", &a[s].yh, &a[s].sj) != EOF) { //EOF输入
s++; //s记录数据个数
}
stable_sort(a, a + s, cmp); //stable_sort和sort的区别是什么
for (i = 0; i < s; i++) {
cout << a[i].yh << ' ' << a[i].sj << endl;
}
return 0;
}
sdnu.1268
#include <bits/stdc++.h>
using namespace std;
struct ys { //定义ys结构体
int xh;
int fs;
};
struct ys a[10005];
bool cmp(ys x, ys y) {
if (x.xh < y.xh) {
return 1;
} else {
return 0;
}
}
int main() {
int N, M;
cin >> N >> M;
int i;
for (i = 0; i < N; i++) {
cin >> a[i].xh >> a[i].fs;
}
for (i = N; i < N + M; i++) {
cin >> a[i].xh >> a[i].fs;
} //这里将两个结构体合并排序
sort(a, a + N + M, cmp);
for (i = 0; i < N + M; i++) {
cout << a[i].xh << ' ' << a[i].fs << endl;
}
return 0;
}
sdnu.1028
#include <bits/stdc++.h>
using namespace std;
struct st { //定义一个st结构体
char name[55];
int ri;
int yue;
int nian;
};
struct st a[1005];
int cmp(st x, st y) {
if (x.nian > y.nian) {
return 0;
} else if (x.nian < y.nian) {
return 1;
} else {
if (x.yue > y.yue) {
return 0;
} else if (x.yue < y.yue) {
return 1;
} else {
if (x.ri > y.ri) {
return 0;
} else if (x.ri < y.ri) {
return 1;
} else {
if (strcmp(x.name, y.name) < 0) {
return 1;
} else {
return 0;
}
}
}
}
} //这里cmp函数看似复杂,但其实只需搞清楚排列顺序的比较对象。先比nian,再比yue,再比ri,最后才是姓名首字母的比较;
int main() {
int N;
cin >> N;
int i;
for (i = 0; i < N; i++) {
cin >> a[i].name >> a[i].ri >> a[i].yue >> a[i].nian;
}
sort(a, a + N, cmp);
for (i = 0; i < N; i++) {
cout << a[i].name << endl;
}
return 0;
}
sdnu.1012
#include <bits/stdc++.h>
using namespace std;
struct qj { //定义一个qj的结构体
int zb;
int yb;
};
struct qj a[1005];
bool cmp(qj x, qj y) { //对每个区间的左边界从小到大排列,原因是什么呢?
if (x.zb > y.zb) {
return 0;
} else {
return 1;
}
}
int main() {
int n;
cin >> n;
int i;
for (i = 0; i < n; i++) {
scanf("%d %d", &a[i].zb, &a[i].yb);
}
sort(a, a + n, cmp);
int m = n; //这里用m来记录还剩多少区间
for (i = 0; i < n - 1; i++) { //什么情况下需要合并区间尼
if (a[i].yb > a[i + 1].zb && a[i].yb <= a[i + 1].yb) {
m--;
} else if ( a[i].yb >= a[i + 1].yb) {
a[i + 1].yb = a[i].yb;
m--;
}
}
cout << m << endl;
return 0;
}
区间合并问题先将各区间的左边界升序排列可以方便代码计算,详细讲解可以观看b站up主睡不醒的鲤鱼