创建属于你自己的整合类型——结构体的使用
1.结构体简介
1.1.结构体基础语法
如果有多种不同类型的数据,想把他们集合成一个整体,可以使用struct
关键字定义一个结构体。语法如下:
struct 结构体名
{
类型1 变量1,变量2;
类型2 变量1,变量2;
…
}变量一,变量二;//分号不要省略
其中,最后一行定义的变量就是这个结构体类型的变量。可以省略。
结构体中的变量也叫做结构体的属性。
定义结构体变量也可以在主函数内定义,比如:
struct 结构体名 变量名;//struct可以省略
调用结构体成员的语法如下:
结构体变量名.成员变量名;
1.2.例题1——最厉害的学生(结构体排序)
题目描述
现有 N N N 名同学参加了期末考试,并且获得了每名同学的信息:姓名(不超过 8 8 8 个字符的仅有英文小写字母的字符串)、语文、数学、英语成绩(均为不超过 150 150 150 的自然数)。总分最高的学生就是最厉害的,请输出最厉害的学生各项信息(姓名、各科成绩)。如果有多个总分相同的学生,输出靠前的那位。
输入格式
第一行输入一个正整数 N N N,表示学生个数。
第二行开始,往下 N N N 行,对于每一行首先先输入一个字符串表示学生姓名,再输入三个自然数表示语文、数学、英语的成绩。均用空格相隔。
输出格式
输出最厉害的学生。
输入输出样例
输入 #1
3
senpai 114 51 4
lxl 114 10 23
fafa 51 42 60
输出 #1
senpai 114 51 4
提示
数据保证, 1 ≤ N ≤ 1000 1 \leq N \leq 1000 1≤N≤1000,姓名为长度不超过 8 8 8 的字符串,语文、数学、英语成绩均为不超过 150 150 150 的自然数。
题意分析
定义一个结构体,储存每个学生的姓名,语文、数学和英语成绩。然后对结构体进行排序,总分高的靠前。最后输出第一名学生就行了。代码如下:
#include<iostream>
#include<algorithm>
using namespace std;
struct student//定义一个结构体,储存每个学生的信息
{
string name;//储存这个学生的姓名
int chinese,maths,english,sum;//储存这个学生的语数英成绩和总分
int lev;//储存这个学生的输入顺序
};
bool cmp(student a,student b)//自定义排序规则,对结构体进行排序
{
//注意if判断要写在前面,总分一样就输入顺序小的排在前面
if(a.sum==b.sum)
return a.lev<b.lev;
return a.sum>b.sum;//否则返回总分大的排在前面
}
int main()
{
struct student a[1010];//在主函数内定义结构体,struct可以省略
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
//输入每个学生的信息
cin>>a[i].name>>a[i].chinese>>a[i].maths>>a[i].english;
a[i].sum=a[i].chinese+a[i].maths+a[i].english;//计算总分
a[i].lev=i;//储存输入顺序
}
sort(a+1,a+n+1,cmp);//对数组a的a[1]~a[n]排序
cout<<a[1].name<<" "<<a[1].chinese<<" "<<a[1].maths<<" "
<<a[1].english<<endl;//第一名即最厉害的学生
return 0;
}
2.typedef结构体重命名
既然结构体也是一种复合类型,那我们可不可以对结构体进行类型重命名呢?当然可以。我们可以这样重命名:
typedef struct 结构体名
{
结构体成员
}重命名名字;
也可以在主函数内重命名。
typedef 结构体名 重命名名字;
3.(选读)成员函数和构造函数
3.1.成员函数
在结构体内,除了可以定义成员变量,还可以定义成员函数。成员函数,也叫做方法。具体定义方式和普通函数差不多,调用方式和结构体属性的调用也差不多。比如:
struct student
{
string name;
int score;
void in_data()//输入姓名和分数
{
cin>>name>>score;
}
void print_data()//输出姓名和分数
{
cout<<name<<" "<<score<<endl;
}
void change_name(string _name)//改变这个人的名字
{
name=_name;
}
int get_score()//得到这个人的姓名
{
return score;
}
};
比如,上面的结构体,如果在下面由一个叫xiaoming
的变量调用printf_data()
方法,那就是输出小明的姓名和分数,以此类推。
xiaoming.print_data();
注意:结构体内定义的成员函数可以直接访问定义的属性和方法。在结构体外定义的函数必须有一个明确的变量。比如:
struct student
{
int chinese,maths,english;//储存这个学生每一门的分数
void get_socre()//在结构内定义成员函数,可以直接访问
{
cin>>chinese>>maths>>english;
}
};
int get_sum(student x)//计算总分
{
return x.chinese+x.maths+x.english;
}
3.2.构造函数
构造函数可以看做是特殊的成员函数。通常是用来初始化结构体属性的。构造函数基础语法如下:
struct 结构体名
{
结构体名(参数类型1 参数1,参数类型2 参数2,…,参数类型n 参数 n)
{
函数体
}
}
注意:
1)构造函数没有类型,也没有返回值,只可以返回“空”;
2)构造函数名必须和结构体名相同;
3)结构体内自带一个无参的构造函数。如果在结构体内重载了构造函数,需要再定义一个无参的构造函数。具体示例如下。
3.3.例题2——评等级
题目描述
现有 N N N 名同学,每名同学需要设计一个结构体记录以下信息:学号、学业成绩和素质拓展成绩、综合分数(实数)。每行读入同学的学号、学业成绩和素质拓展成绩,并且计算综合分数(分别按照 70 % 70\% 70% 和 30 % 30\% 30% 权重累加),存入结构体中。还需要在结构体中定义一个成员函数,返回该结构体对象的学业成绩和素质拓展成绩的总分。
然后需要设计一个函数,其参数是一个学生结构体对象,判断该学生是否“优秀”。优秀的定义是学业和素质拓展成绩总分大于 140 140 140 分,且综合分数不小于 80 80 80 分。
当然通过本题很容易啦,本题只是为了帮助你训练结构体的使用方法。
本题存在精度误差问题,请将 a * 0.7 + b * 0.3
与 80 比较 转化为 a * 7 + b * 3
与 800 比较。
输入格式
第一行一个整数 N N N。
接下来 N N N 行,每行 3 3 3 个整数,依次代表学号、学业成绩和素质拓展成绩。
输出格式
N
N
N 行,如果第
i
i
i 名学生是优秀的,输出 Excellent
,否则输出 Not excellent
。
输入输出样例
输入 #1
4
1223 95 59
1224 50 7
1473 32 45
1556 86 99
输出 #1
Excellent
Not excellent
Not excellent
Excellent
提示
数据保证, 1 ≤ N ≤ 1000 1 \le N\le 1000 1≤N≤1000,学号为不超过 100000 100000 100000 的正整数,学业成绩和素质拓展成绩为 0 ∼ 100 0 \sim 100 0∼100 之间的正整数。
题意分析
按题意模拟就行。
代码
#include<iostream>
using namespace std;
int n,x,ans;
struct student
{
int id,academic,quality;
double overall;
student(int _id,int _ac,int _qu)//初始化构造函数
{
id=_id;//分别储存学号、学业成绩和素质拓展成绩
academic=_ac;//给学业成绩赋值
quality=_qu;//计算综合成绩
overall=0.7*_ac+0.3*_qu;//这里的this->可以省略
}
student(){}//没有传递参数的初始化构造函数
int sum()//计算分数总和
{
return academic+quality;
}
};
bool is_excellent(student s)
{//访问成员变量与调用成员函数
return s.overall>=80&&s.sum()>140;
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
int tmp_id,tmp_ac,tmp_qu;
cin>>tmp_id>>tmp_ac>>tmp_qu;
student one_student(tmp_id,tmp_ac,tmp_qu);//结构体初始化
if(is_excellent(one_student))//结构体变量作为参数传递
cout<<"Excellent"<<endl;
else
cout<<"Not excellent"<<endl;
}
return 0;
}
4.(选读)结构体成员访问属性
在结构体中,我们可以定义公开的属性和方法,也可以定义私有的属性和方法。可以使用public
private
和protected
关键字实现这个功能。结构体内的属性默认是公开的(public
)。这里只需要大概了解一下就行了,感兴趣可以自己上网查阅资料。
喜欢就订阅此专辑吧!
【蓝胖子编程教育简介】
蓝胖子编程教育,是一家面向青少年的编程教育平台。平台为全国青少年提供最专业的编程教育服务,包括提供最新最详细的编程相关资讯、最专业的竞赛指导、最合理的课程规划等。本平台利用趣味性和互动性强的教学方式,旨在激发孩子们对编程的兴趣,培养他们的逻辑思维能力和创造力,让孩子们在轻松愉快的氛围中掌握编程知识,为未来科技人才的培养奠定坚实基础。
欢迎扫码关注蓝胖子编程教育