目录
前言:
dfs(depth first search深度优先搜索)的博客写到一半,遇到了迷宫,涉及到结构体,所以回来复习一下
一,结构体基础
1,题目
请帮老师写一个程序,要求存储本年级100个学生的姓名,学号,语文,英语,数学三门课的成绩,并根据语文成绩递减顺序,输出所有学生信息
这里简化为4个学生,结果是一样的
2,代码
#include<iostream>
#include<stdio.h>//scanf(), printf()
using namespace std;
const int n = 4, m = 20;//整型常量
typedef struct student
{
char name[m];//成员名name
int number;//成员名number
float chinese;
float english;
float math;
}stu;
int main()
{
stu s[n], temp;//变量名s1, 变量名temp
//for循环中++i等价于i++, 且++i更节省空间速度更快
//变量名.成员名访问结构体元素
for(int i = 0; i < n; ++i)
scanf("%s %d %f %f %f", s[i].name, &s[i].number,
&s[i].chinese, &s[i].english, &s[i].math);
printf("\n");
for(int i = 0; i < n; ++i)
{
int Max = i;//记录语文成绩最大值位置
for(int j = i+1; j < n; ++j)
if(s[j].chinese > s[Max].chinese)
{
temp = s[j];//因为s[j]为结构体变量,所以temp也得是
s[j] = s[Max];
s[Max] = temp;//选择排序,最大值放前面
}
}
for(int i = 0; i < n; ++i)
printf("%s %d %.2f %.2f %.2f\n", s[i].name, s[i].number,
s[i].chinese, s[i].english, s[i].math);
return 0;
}
输入输出
QQ 4 67 89 78
Ten 2 99 12 62
albion 1 77 66 55
apex 3 69 51 100
Ten 2 99.00 12.00 62.00
albion 1 77.00 66.00 55.00
apex 3 69.00 51.00 100.00
QQ 4 67.00 89.00 78.00
3,分析
0,关于代码第21行scanf中s[i].name前没有取地址符
因为C++中字符串名和数组名都表示其地址,所以输入时不需要加"&"
而单独的字符、整型变量等不能直接表示地址,所以要加取地址符
1,结构体把它的所有成员看作一个整体,这些成员可以是不同类型的变量,比如int q, char a[], float n, char c,也可以是结构体,struct是关键字
2,结构体的定义
注意,结构体本身也是一种数据类型,类似int, char等,不过是自定义的罢了
struct 结构名
{
类型名1 成员名1;
类型名2 成员名2;
类型名3 成员名3;
};
或者
typedef struct 结构名
{
类型名1 成员名1;
类型名2 成员名2;
类型名3 成员名3;
}stu;
typedef是类型定义符,eg:把struct student定义成stu,后面再定义变量就省事点
stu是随便编的,不和什么类型名等冲突就行
{}后的";"不要漏
3,结构体变量的定义
//以题目代码为例
typedef struct student
{
...
...
}stu;
stu s[20];
或者
//以题目代码为例
typedef struct student
{
...
...
};
struct student s[20];
两者等价
4,同类型的结构变量可以彼此赋值
比如stu s1, s2 = {"apex", 2, 99, 88, 77};
//结构student需要提供姓名,学号,三科成绩,所以变量s2的初始化对应5个数据
s1 = s2;
s1, s2都属于student(题目代码中的结构体类型名)这种类型,所以类型相同
5,结构变量中成员的引用(访问)
结构变量名.结构成员名,这里的 "."可以读作"的",比如s.name读作"s变量的name成员"
6,结构变量初始化和赋值例子
代码
#include<iostream>
#include<stdio.h>//scanf(), printf()
using namespace std;
struct person
{
char name[20];
long long id;
float salary;
};
int main()
{//下面结构变量初始化
struct person pr1 = {"apex", 20222010085, 12500};
struct person pr2;
pr2 = pr1; //结构体变量互相赋值
printf("%s\t%lld\t%.1f", pr2.name, pr2.id, pr2.salary);
return 0;
}
输出
apex 20222010085 12500.0
👀 👀 👀去MOOC找找二和三的原题目 👀 👀 👀
二,结构体排序
1,代码
#include<iostream>
#include<algorithm>//sort()
#include<iomanip> //setprecision(), setiosflags(ios::fixed)
#include<string.h> //strcmp(s1,s2),比较两字符串大小,s1 > s2输出正数
using namespace std;
struct book
{
char name[50];//书名
float price;//价格
int classification;//类别编号
};
bool cmp(book x, book y)
{
if(x.price != y.price)
return x.price < y.price;
return strcmp(x.name,y.name) > 0;//仿函数,类似lambda的功能
}//return strcmp(x.name,y.name) < 0结合strcmp()函数可知按从小到大返回
//比较器函数和结构体最好一起放主函数外,不能在一个函数中定义另一个函数
int main()
{
struct book s[101];
int n;
cin>>n;//n本书
for(int i = 0; i < n; i++)
{
cin>>s[i].name>>s[i].price>>s[i].classification;
//变量名.成员名访问结构体的成员
}
sort(s,s+n,cmp);//sort(起始地址,结束地址,比较器)
for(int i = 0; i < n; i++)
cout<<s[i].name<<","<<setprecision(2)<<setiosflags(ios::fixed)
<<s[i].price<<","<<s[i].classification<<endl;
return 0;
}
输入输出
4
Englishbook 25 1
Chinese 35 1
CHINESE 35 1
Indian 15 1
Indian,15.00,1
Englishbook,25.00,1
Chinese,35.00,1
CHINESE,35.00,1
2,分析:
1,结构体变量初始化和赋值还可以直接从键盘输入
for(int i = 0; i < n; i++)
{
cin>>s[i].name>>s[i].price>>s[i].classification;
}
2,代码中的bool函数最后,
if(x.price != y.price)
return x.price < y.price;
意思是如果两本书价格不一样,按从小到大的顺序输出
如果价格一样,按字符串从大到小输出
return strcmp(x.name,y.name) > 0
三,键盘输入学号,分析学生信息
1,代码
#include<iostream>
#include<stdio.h> //scanf,printf
using namespace std;
typedef struct student//定义struct student学生这种结构
{
char grade[5];
char department[3];//都是字符数组类型
char major[3];//都比实际长度多一位,以便存放字符串结束符'\0'
char cclass[3];//共五个成员
char number[4];
}student;
int main()
{
char number[14];//13 + 1 == 14, 留一个位置给结束符'\0'
student s;//定义了student结构的变量s
int i;
scanf("%s", number, 13);//读入字符串要指明读入多少个字符,这里13个
//数组名number表示数组首地址,所以前面不需要取地址符'&'
for(i = 0; i < 4; i++) //0,1,2,3,将number中四个数据复制到grade成员中
s.grade[i] = number[i];//变量名.成员名访问成员
s.grade[i] = '\0';// i = 4
s.department[0] = number[i++];//第5个数据, i = 4
s.department[1] = number[i++];
s.department[2] = '\0';
s.major[0] = number[i++];
s.major[1] = number[i++];
s.major[2] = '\0';
s.cclass[0] = number[i++];
s.cclass[1] = number[i++];
s.cclass[2] = '\0';
s.number[0] = number[i++];
s.number[1] = number[i++];
s.number[2] = number[i++];//第13个数据,i = 12
s.number[3] = '\0';//长度14
printf("学院:%s;专业:%s;年级:%s;班:%s;学号:%s\n",
s.department, s.major, s.grade, s.cclass, s.number);
//以%s的形式按字符串输出
return 0;
}
输入输出
2022020104325
学院:02;专业:01;年级:2022;班:04;学号:325
2,分析:
(请看注释)
1,该结构体共5个成员,年级,学院,专业,班级,学号
2,结构体中的成员变量名,与非结构体变量没有关系,可以相同,所以有个成员变量名number[4],还有个主函数中的变量名number[14],
所以可以和成员名重复,但不能和结构体类型名重复,比如本题代码中的student
3,根据代码,输入按年级,学院,专业,班级,学号的顺序,输出按学院,专业,年级,班级,学号的顺序
本文详细介绍结构体的基础概念、排序及信息解析的应用实例,包括学生信息管理、书籍排序及学号解析,适合初学者掌握结构体的使用技巧。
1万+

被折叠的 条评论
为什么被折叠?



