结构体能够将一些不同类型的信息“捆绑”聚合成一个整体,例如可以用一个结构体来记录学生的姓名(字符串类型)、性别(char类型)、年龄(int类型)等信息。结构体就像int、double一样,是一种(自定义的)数据类型。
一、结构体的基本使用方法
先来看一个问题:P5740 【深基7.例9】最厉害的学生
分析:使用“打擂台”方式求极值,只不过这里要记录下最高分的学生的姓名和三科成绩:
int n,chinese,math,english,total;
int ans_chinese,ans_math,ans_english,ans_total;
cin>>name>>chinese>>math>>english;
total = chinese+math+english;
cout<<ans_name<<" "<<ans_chinese<<" "<<ans_math<<" "<<ans_english<<endl;
#include<iostream>
#include<string>
using namespace std;
int main()
{
string name,ans_name;
int n,chinese,math,english,total;
int ans_chinese,ans_math,ans_english,ans_total;
ans_total = 0;
cin>>n;
for(int i=1;i<=n;i++){
cin>>name>>chinese>>math>>english;
total = chinese+math+english;
if(total>ans_total){
ans_total = total;
ans_name= name;
ans_chinese = chinese;
ans_math = math;
ans_english = english;
}
}
cout<<ans_name<<" "<<ans_chinese<<" "<<ans_math<<" "<<ans_english<<endl;
return 0;
}
#include<iostream>
#include<string>
using namespace std;
int main()
{
string name,ans_name;
int n,chinese,math,english,total;
int ans_chinese,ans_math,ans_english,ans_total;
ans_total = 0;
cin>>n;
for(int i=1;i<=n;i++){
cin>>name>>chinese>>math>>english;
total = chinese+math+english;
if(total>ans_total){
ans_total = total;
ans_name= name;
ans_chinese = chinese;
ans_math = math;
ans_english = english;
}
}
cout<<ans_name<<" "<<ans_chinese<<" "<<ans_math<<" "<<ans_english<<endl;
return 0;
}
上面的程序使用了5个变量来存储每次输入的学生姓名、语文、数学、英语和总分5项信息,同样用5个变量记录了最高分学生的5项信息,“打擂”过程中,遇到新的最高分,记录最高分学生的5项信息都要更新,这样操作有点繁琐。
可以使用结构体将学生的5项信息“捆绑打包”聚合成一个自定义数据类型:
//定义一个结构体Student来记录学生信息,Student是一个自定义数据类型
//结构体中name、chinese等是Student的成员变量(书写就像定义普通变量一样)
int chinese,math,english,total;
//one用来记录每次输入的学生信息,ans记录最高分学生信息
//输入到one的name、chinese、math、english成员变量中
cin>>one.name>>one.chinese>>one.math>>one.english;
one.total = one.chinese+one.math+one.english;
ans = one; //非常简单的直接赋值来记录最高分学生信息
cout<<ans.name<<" "<<ans.chinese<<" "<<ans.math<<" "<<ans.english<<endl;
#include<iostream>
#include<string>
using namespace std;
//定义一个结构体Student来记录学生信息,Student是一个自定义数据类型
//结构体中name、chinese等是Student的成员变量(书写就像定义普通变量一样)
struct Student{
string name;
int chinese,math,english,total;
};
int main()
{
//定义Student类型变量one和ans
//one用来记录每次输入的学生信息,ans记录最高分学生信息
Student one,ans;
ans.total = 0;
int n;
cin>>n;
for(int i=1;i<=n;i++){
//输入到one的name、chinese、math、english成员变量中
cin>>one.name>>one.chinese>>one.math>>one.english;
//计算one的total成员变量
one.total = one.chinese+one.math+one.english;
if(one.total>ans.total){
ans = one; //非常简单的直接赋值来记录最高分学生信息
}
}
cout<<ans.name<<" "<<ans.chinese<<" "<<ans.math<<" "<<ans.english<<endl;
return 0;
}
#include<iostream>
#include<string>
using namespace std;
//定义一个结构体Student来记录学生信息,Student是一个自定义数据类型
//结构体中name、chinese等是Student的成员变量(书写就像定义普通变量一样)
struct Student{
string name;
int chinese,math,english,total;
};
int main()
{
//定义Student类型变量one和ans
//one用来记录每次输入的学生信息,ans记录最高分学生信息
Student one,ans;
ans.total = 0;
int n;
cin>>n;
for(int i=1;i<=n;i++){
//输入到one的name、chinese、math、english成员变量中
cin>>one.name>>one.chinese>>one.math>>one.english;
//计算one的total成员变量
one.total = one.chinese+one.math+one.english;
if(one.total>ans.total){
ans = one; //非常简单的直接赋值来记录最高分学生信息
}
}
cout<<ans.name<<" "<<ans.chinese<<" "<<ans.math<<" "<<ans.english<<endl;
return 0;
}
结构体是由一系列数据(可以是不同的数据类型)构成的数据集合,并且结构体提供了一种自定义数据类型的手段。定义结构体的一般格式如下:
struct 类型名称{
数据类型1 成员变量1(或者成员变量列表);
数据类型2 成员变量2(或者成员变量列表);
//...其它成员变量
};
struct 类型名称{
数据类型1 成员变量1(或者成员变量列表);
数据类型2 成员变量2(或者成员变量列表);
//...其它成员变量
};
结构体定义的是一种数据类型,所以可以像申明int、double、string类型的变量那样来申明结构体变量。此外,可以用结构体变量名.成员名
来使用结构体内部的成员变量,这些成员变量的使用方法和普通的变量一致,可以输入、输出、赋值、参加运算(上面例子中cin>>one.xm>>one.yw>>one.sx>>one.yy;
、one.zf = one.yw+one.sx+one.yy;
、one.zf>ans.zf
)。更神奇的是,相同类型的结构体变量之间可以直接赋值(上面例子中更新最高分学生信息时直接使用ans = one;
)。
其实结构体中的成员变量也可以是结构体类型,例如上面的例子可以将成绩信息定义为一个Score结构体类型,学生信息定义为一个Student结构体类型,Student结构体中用一个Score结构体类型成员变量记录所有成绩信息:
int chinese,math,english,total;
cin>>one.name>>one.score.chinese>>one.score.math>>one.score.english;
one.score.total = one.score.chinese+one.score.math+one.score.english;
if(one.score.total>ans.score.total){
cout<<ans.name<<" "<<ans.score.chinese<<" "<<ans.score.math<<" "<<ans.score.english<<endl;
#include<iostream>
#include<string>
using namespace std;
struct Score{
int chinese,math,english,total;
};
struct Student{
string name;
Score score;
};
int main()
{
Student one,ans;
ans.score.total = 0;
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>one.name>>one.score.chinese>>one.score.math>>one.score.english;
one.score.total = one.score.chinese+one.score.math+one.score.english;
if(one.score.total>ans.score.total){
ans = one;
}
}
cout<<ans.name<<" "<<ans.score.chinese<<" "<<ans.score.math<<" "<<ans.score.english<<endl;
return 0;
}
#include<iostream>
#include<string>
using namespace std;
struct Score{
int chinese,math,english,total;
};
struct Student{
string name;
Score score;
};
int main()
{
Student one,ans;
ans.score.total = 0;
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>one.name>>one.score.chinese>>one.score.math>>one.score.english;
one.score.total = one.score.chinese+one.score.math+one.score.english;
if(one.score.total>ans.score.total){
ans = one;
}
}
cout<<ans.name<<" "<<ans.score.chinese<<" "<<ans.score.math<<" "<<ans.score.english<<endl;
return 0;
}
二、结构体数组
问题:P5741 旗鼓相当的对手 - 加强版
分析:用结构体Student存储一位学生信息,用结构体Student数组a来存储所有学生信息。通过循环列举1~N-1的每位学生a[i],对于a[i]判断其与i+1~N的每位学生a[j]是否是“旗鼓相当的对手”即可(这样不会出现重复判断):
int chinese,math,english,total;
bool judge(int x,int y,int z){ //判断|x-y|<=z?
bool check(Student a,Student b){ //判断a、b两位学生是否是“旗鼓相当的对手”
return judge(a.chinese,b.chinese,5) && judge(a.math,b.math,5) && judge(a.english,b.english,5) && judge(a.total,b.total,10);
cin>>a[i].name>>a[i].chinese>>a[i].math>>a[i].english;
a[i].total = a[i].chinese+a[i].math+a[i].english;
//从第i+1位开始的每位学生a[j],判断a[i]与a[j]
cout<<a[i].name<<" "<<a[j].name<<endl;
#include<iostream>
#include<string>
using namespace std;
struct Student{
string name;
int chinese,math,english,total;
};
Student a[1001];
bool judge(int x,int y,int z){ //判断|x-y|<=z?
return x-y<=z && y-x<=z;
}
bool check(Student a,Student b){ //判断a、b两位学生是否是“旗鼓相当的对手”
return judge(a.chinese,b.chinese,5) && judge(a.math,b.math,5) && judge(a.english,b.english,5) && judge(a.total,b.total,10);
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i].name>>a[i].chinese>>a[i].math>>a[i].english;
a[i].total = a[i].chinese+a[i].math+a[i].english;
}
for(int i=1;i<n;i++){
//从第i+1位开始的每位学生a[j],判断a[i]与a[j]
for(int j=i+1;j<=n;j++){
if(check(a[i],a[j])){
cout<<a[i].name<<" "<<a[j].name<<endl;
}
}
}
return 0;
}
#include<iostream>
#include<string>
using namespace std;
struct Student{
string name;
int chinese,math,english,total;
};
Student a[1001];
bool judge(int x,int y,int z){ //判断|x-y|<=z?
return x-y<=z && y-x<=z;
}
bool check(Student a,Student b){ //判断a、b两位学生是否是“旗鼓相当的对手”
return judge(a.chinese,b.chinese,5) && judge(a.math,b.math,5) && judge(a.english,b.english,5) && judge(a.total,b.total,10);
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i].name>>a[i].chinese>>a[i].math>>a[i].english;
a[i].total = a[i].chinese+a[i].math+a[i].english;
}
for(int i=1;i<n;i++){
//从第i+1位开始的每位学生a[j],判断a[i]与a[j]
for(int j=i+1;j<=n;j++){
if(check(a[i],a[j])){
cout<<a[i].name<<" "<<a[j].name<<endl;
}
}
}
return 0;
}
三、*结构体成员函数
结构体中除了成员变量外,还可以有成员函数,成员函数类似于函数,可以认为它是结构体的“内部函数”,看下面的例子:
int chinese,math,english;
cout<<name<<" "<<chinese<<" "<<math<<" "<<english<<endl;
return chinese+math+english;
cout<<one.total()<<endl; //调用成员函数(有返回值)
#include<iostream>
#include<string>
using namespace std;
struct Student{
string name;
int chinese,math,english;
//成员函数(输出学生姓名和三科成绩)
void print(){
cout<<name<<" "<<chinese<<" "<<math<<" "<<english<<endl;
}
//有返回值的成员函数(计算三科成绩总分)
int total(){
return chinese+math+english;
}
};
int main()
{
Student one;
one.name = "Jerry";
one.chinese = 120;
one.math = 138;
one.english = 145;
one.print(); //调用成员函数
cout<<one.total()<<endl; //调用成员函数(有返回值)
return 0;
}
#include<iostream>
#include<string>
using namespace std;
struct Student{
string name;
int chinese,math,english;
//成员函数(输出学生姓名和三科成绩)
void print(){
cout<<name<<" "<<chinese<<" "<<math<<" "<<english<<endl;
}
//有返回值的成员函数(计算三科成绩总分)
int total(){
return chinese+math+english;
}
};
int main()
{
Student one;
one.name = "Jerry";
one.chinese = 120;
one.math = 138;
one.english = 145;
one.print(); //调用成员函数
cout<<one.total()<<endl; //调用成员函数(有返回值)
return 0;
}
结构体有一种特殊的成员函数,其函数名与结构体名称相同,称为构造函数,可以用来初始化结构体:
int chinese,math,english;
Student(){} //没有任何参数的(默认)构造函数
//带参数的构造函数(参数名和成员名不同,特意加了一个_)
Student(string _name,int _chinese,int _math,int _english){
this->name = _name; //可以简写成 name = _name; name是结构体成员,_name是参数
this->chinese = _chinese;
this->english = _english;
//注意比较和上面定义结构体的不同(带参构造函数的名称)
int chinese,math,english;
Student(){} //没有任何参数的(默认)构造函数
Student(string name,int chinese,int math,int english){
this->name = name; //不能简写成 name = name;因为参数(局部变量)name将同名的成员name屏蔽了
struct Student{
string name;
int chinese,math,english;
Student(){} //没有任何参数的(默认)构造函数
//带参数的构造函数(参数名和成员名不同,特意加了一个_)
Student(string _name,int _chinese,int _math,int _english){
this->name = _name; //可以简写成 name = _name; name是结构体成员,_name是参数
this->chinese = _chinese;
this->math = _math;
this->english = _english;
}
};
//注意比较和上面定义结构体的不同(带参构造函数的名称)
struct Student{
string name;
int chinese,math,english;
Student(){} //没有任何参数的(默认)构造函数
//带参数的构造函数(参数名和成员名相同)
Student(string name,int chinese,int math,int english){
this->name = name; //不能简写成 name = name;因为参数(局部变量)name将同名的成员name屏蔽了
this->chinese = chinese;
this->math = math;
this->english = english;
}
};
struct Student{
string name;
int chinese,math,english;
Student(){} //没有任何参数的(默认)构造函数
//带参数的构造函数(参数名和成员名不同,特意加了一个_)
Student(string _name,int _chinese,int _math,int _english){
this->name = _name; //可以简写成 name = _name; name是结构体成员,_name是参数
this->chinese = _chinese;
this->math = _math;
this->english = _english;
}
};
//注意比较和上面定义结构体的不同(带参构造函数的名称)
struct Student{
string name;
int chinese,math,english;
Student(){} //没有任何参数的(默认)构造函数
//带参数的构造函数(参数名和成员名相同)
Student(string name,int chinese,int math,int english){
this->name = name; //不能简写成 name = name;因为参数(局部变量)name将同名的成员name屏蔽了
this->chinese = chinese;
this->math = math;
this->english = english;
}
};
上面代码定义的结构体Student中有两个构造函数,一个是没有任何参数的Student();
另外一个是有参数的Student(string _name,int _chinese,int _math,int _english);
有了构造函数,就可以用构造函数来初始化结构体:
Student ss = Student("Jerry",120,135,150);
Student sss("Jerry",120,135,150);
//原始的初始化结构体变量方法
Student s;
s.name= "Jerry";
s.chinese = 120;
s.math = 135;
s.english = 150;
//借助结构体构造函数初始化后赋值给结构体变量
Student ss = Student("Jerry",120,135,150);
//使用结构体的构造函数直接初始化结构体变量
Student sss("Jerry",120,135,150);
//原始的初始化结构体变量方法
Student s;
s.name= "Jerry";
s.chinese = 120;
s.math = 135;
s.english = 150;
//借助结构体构造函数初始化后赋值给结构体变量
Student ss = Student("Jerry",120,135,150);
//使用结构体的构造函数直接初始化结构体变量
Student sss("Jerry",120,135,150);
下面来看成员函数的示例程序:
int chinese,math,english;
Student(){} //没有任何参数的(默认)构造函数
Student(string _name,int _chinese,int _math,int _english){
this->name = _name; //可以简写成 name = _name;
this->chinese = _chinese;
this->english = _english;
return chinese+math+english;
cout<<name<<" "<<chinese<<" "<<math<<" "<<english<<endl;
Student s("Jerry",120,135,150);
cout<<s.total()<<endl; //调用结构体成员方法
#include<iostream>
#include<string>
using namespace std;
struct Student{
string name;
int chinese,math,english;
Student(){} //没有任何参数的(默认)构造函数
Student(string _name,int _chinese,int _math,int _english){
this->name = _name; //可以简写成 name = _name;
this->chinese = _chinese;
this->math = _math;
this->english = _english;
}
int total(){
return chinese+math+english;
}
void print(){
cout<<name<<" "<<chinese<<" "<<math<<" "<<english<<endl;
}
};
int main()
{
//使用结构体的构造函数初始化变量
Student s("Jerry",120,135,150);
cout<<s.total()<<endl; //调用结构体成员方法
s.print(); //调用结构体成员方法
return 0;
}
#include<iostream>
#include<string>
using namespace std;
struct Student{
string name;
int chinese,math,english;
Student(){} //没有任何参数的(默认)构造函数
Student(string _name,int _chinese,int _math,int _english){
this->name = _name; //可以简写成 name = _name;
this->chinese = _chinese;
this->math = _math;
this->english = _english;
}
int total(){
return chinese+math+english;
}
void print(){
cout<<name<<" "<<chinese<<" "<<math<<" "<<english<<endl;
}
};
int main()
{
//使用结构体的构造函数初始化变量
Student s("Jerry",120,135,150);
cout<<s.total()<<endl; //调用结构体成员方法
s.print(); //调用结构体成员方法
return 0;
}
通过上面的例子,我们应该能够体会到前面使用string类型变量的length()方法获取字符串长度(string s;cin>>s;cout<<s.length();
),其实string是一个类(和结构体相似,但功能比结构体更强),length是其中的成员函数(又称为方法)。
C++还支持更简洁的结构体初始化语句:
int chinese,math,english;
Student s{"Jerry",120,135,150};
cout<<s.name<<" "<<s.chinese<<" "<<s.math<<" "<<s.english<<endl;
#include<iostream>
#include<string>
using namespace std;
struct Student{
string name;
int chinese,math,english;
};
int main()
{
//更简洁的结构体初始化语句
Student s{"Jerry",120,135,150};
cout<<s.name<<" "<<s.chinese<<" "<<s.math<<" "<<s.english<<endl;
return 0;
}
#include<iostream>
#include<string>
using namespace std;
struct Student{
string name;
int chinese,math,english;
};
int main()
{
//更简洁的结构体初始化语句
Student s{"Jerry",120,135,150};
cout<<s.name<<" "<<s.chinese<<" "<<s.math<<" "<<s.english<<endl;
return 0;
}
借助成员方法,上一个问题“P5741 旗鼓相当的对手 - 加强版”还可以如下求解:
int chinese,math,english;
Student(){} //没有任何参数的(默认)构造函数
Student(string _name,int _chinese,int _math,int _english){
this->name = _name; //可以简写成 name = _name;
this->chinese = _chinese;
this->english = _english;
return chinese+math+english;
bool judge(int x,int y,int z){ //判断|x-y|<=z?
bool check(Student a) { //判断当前学生与学生a是否是“旗鼓相当的对手”
return judge(chinese,a.chinese,5) && judge(math,a.math,5) && judge(english,a.english,5) && judge(total(),a.total(),10);
int chinese,math,english;
cin>>name>>chinese>>math>>english;
a[i] = Student(name,chinese,math,english);
//从第i+1位开始的每位学生a[j],判断a[i]与a[j]
cout<<a[i].name<<" "<<a[j].name<<endl;
#include<iostream>
#include<string>
using namespace std;
struct Student{
string name;
int chinese,math,english;
Student(){} //没有任何参数的(默认)构造函数
Student(string _name,int _chinese,int _math,int _english){
this->name = _name; //可以简写成 name = _name;
this->chinese = _chinese;
this->math = _math;
this->english = _english;
}
int total(){ //计算返回总分
return chinese+math+english;
}
bool judge(int x,int y,int z){ //判断|x-y|<=z?
return x-y<=z && y-x<=z;
}
bool check(Student a) { //判断当前学生与学生a是否是“旗鼓相当的对手”
return judge(chinese,a.chinese,5) && judge(math,a.math,5) && judge(english,a.english,5) && judge(total(),a.total(),10);
}
};
Student a[1001];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++){
string name;
int chinese,math,english;
cin>>name>>chinese>>math>>english;
a[i] = Student(name,chinese,math,english);
}
for(int i=1;i<n;i++){
//从第i+1位开始的每位学生a[j],判断a[i]与a[j]
for(int j=i+1;j<=n;j++){
if(a[i].check(a[j])){
cout<<a[i].name<<" "<<a[j].name<<endl;
}
}
}
return 0;
}
#include<iostream>
#include<string>
using namespace std;
struct Student{
string name;
int chinese,math,english;
Student(){} //没有任何参数的(默认)构造函数
Student(string _name,int _chinese,int _math,int _english){
this->name = _name; //可以简写成 name = _name;
this->chinese = _chinese;
this->math = _math;
this->english = _english;
}
int total(){ //计算返回总分
return chinese+math+english;
}
bool judge(int x,int y,int z){ //判断|x-y|<=z?
return x-y<=z && y-x<=z;
}
bool check(Student a) { //判断当前学生与学生a是否是“旗鼓相当的对手”
return judge(chinese,a.chinese,5) && judge(math,a.math,5) && judge(english,a.english,5) && judge(total(),a.total(),10);
}
};
Student a[1001];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++){
string name;
int chinese,math,english;
cin>>name>>chinese>>math>>english;
a[i] = Student(name,chinese,math,english);
}
for(int i=1;i<n;i++){
//从第i+1位开始的每位学生a[j],判断a[i]与a[j]
for(int j=i+1;j<=n;j++){
if(a[i].check(a[j])){
cout<<a[i].name<<" "<<a[j].name<<endl;
}
}
}
return 0;
}
四、*重载输入输出运算符输入输出结构体变量
上面的程序输入并存储到结构体变量的语句仍然比较繁琐,可以重载输入运算符实现直接输入成员数据存储到结构体变量中,同样地还可以重载输出运算符实现直接输出结构体变量。
int chinese,math,english;
Student(){} //没有任何参数的(默认)构造函数
Student(string _name,int _chinese,int _math,int _english){
this->name = _name; //可以简写成 name = _name;
this->chinese = _chinese;
this->english = _english;
return chinese+math+english;
bool judge(int x,int y,int z){ //判断|x-y|<=z?
bool check(Student a) { //判断当前学生与学生a是否是“旗鼓相当的对手”
return judge(chinese,a.chinese,5) && judge(math,a.math,5) && judge(english,a.english,5) && judge(total(),a.total(),10);
istream &operator>>(istream &in, Student &s){
in>>s.name>>s.chinese>>s.math>>s.english;
ostream &operator<<(ostream &os,Student &s){
//os<<s.name<<" "<<s.chinese<<" "<<s.math<<" "<<s.english<<" "<<s.total()<<endl;
cin>>a[i]; //因为重载了输入运算符,这里可以直接用cin>>a[i];
//从第i+1位开始的每位学生a[j],判断a[i]与a[j]
cout<<a[i]<<" "<<a[j]<<endl; //因为重载了输出运算符,这里可以直接用cout<<a[i];
#include<iostream>
#include<string>
using namespace std;
struct Student{
string name;
int chinese,math,english;
Student(){} //没有任何参数的(默认)构造函数
Student(string _name,int _chinese,int _math,int _english){
this->name = _name; //可以简写成 name = _name;
this->chinese = _chinese;
this->math = _math;
this->english = _english;
}
int total(){ //计算返回总分
return chinese+math+english;
}
bool judge(int x,int y,int z){ //判断|x-y|<=z?
return x-y<=z && y-x<=z;
}
bool check(Student a) { //判断当前学生与学生a是否是“旗鼓相当的对手”
return judge(chinese,a.chinese,5) && judge(math,a.math,5) && judge(english,a.english,5) && judge(total(),a.total(),10);
}
};
Student a[1001];
//重载输入运算符
istream &operator>>(istream &in, Student &s){
in>>s.name>>s.chinese>>s.math>>s.english;
return in;
}
//重载输出运算符
ostream &operator<<(ostream &os,Student &s){
//os<<s.name<<" "<<s.chinese<<" "<<s.math<<" "<<s.english<<" "<<s.total()<<endl;
os<<s.name;
return os;
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i]; //因为重载了输入运算符,这里可以直接用cin>>a[i];
}
for(int i=1;i<n;i++){
//从第i+1位开始的每位学生a[j],判断a[i]与a[j]
for(int j=i+1;j<=n;j++){
if(a[i].check(a[j])){
cout<<a[i]<<" "<<a[j]<<endl; //因为重载了输出运算符,这里可以直接用cout<<a[i];
}
}
}
return 0;
}
#include<iostream>
#include<string>
using namespace std;
struct Student{
string name;
int chinese,math,english;
Student(){} //没有任何参数的(默认)构造函数
Student(string _name,int _chinese,int _math,int _english){
this->name = _name; //可以简写成 name = _name;
this->chinese = _chinese;
this->math = _math;
this->english = _english;
}
int total(){ //计算返回总分
return chinese+math+english;
}
bool judge(int x,int y,int z){ //判断|x-y|<=z?
return x-y<=z && y-x<=z;
}
bool check(Student a) { //判断当前学生与学生a是否是“旗鼓相当的对手”
return judge(chinese,a.chinese,5) && judge(math,a.math,5) && judge(english,a.english,5) && judge(total(),a.total(),10);
}
};
Student a[1001];
//重载输入运算符
istream &operator>>(istream &in, Student &s){
in>>s.name>>s.chinese>>s.math>>s.english;
return in;
}
//重载输出运算符
ostream &operator<<(ostream &os,Student &s){
//os<<s.name<<" "<<s.chinese<<" "<<s.math<<" "<<s.english<<" "<<s.total()<<endl;
os<<s.name;
return os;
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i]; //因为重载了输入运算符,这里可以直接用cin>>a[i];
}
for(int i=1;i<n;i++){
//从第i+1位开始的每位学生a[j],判断a[i]与a[j]
for(int j=i+1;j<=n;j++){
if(a[i].check(a[j])){
cout<<a[i]<<" "<<a[j]<<endl; //因为重载了输出运算符,这里可以直接用cout<<a[i];
}
}
}
return 0;
}