创建属于你自己的整合类型——结构体的使用

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 1N1000,姓名为长度不超过 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 1N1000,学号为不超过 100000 100000 100000 的正整数,学业成绩和素质拓展成绩为 0 ∼ 100 0 \sim 100 0100 之间的正整数。

题意分析
按题意模拟就行。

代码

#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 privateprotected关键字实现这个功能。结构体内的属性默认是公开的(public)。这里只需要大概了解一下就行了,感兴趣可以自己上网查阅资料。

喜欢就订阅此专辑吧!

【蓝胖子编程教育简介】
蓝胖子编程教育,是一家面向青少年的编程教育平台。平台为全国青少年提供最专业的编程教育服务,包括提供最新最详细的编程相关资讯、最专业的竞赛指导、最合理的课程规划等。本平台利用趣味性和互动性强的教学方式,旨在激发孩子们对编程的兴趣,培养他们的逻辑思维能力和创造力,让孩子们在轻松愉快的氛围中掌握编程知识,为未来科技人才的培养奠定坚实基础。

欢迎扫码关注蓝胖子编程教育
在这里插入图片描述

  • 26
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝胖子教编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值