这块一直有些没整明白,抽空把能想到的系统总结一下
1.结构体定义
struct student//类型名称
{
//可放基本的数据类型或者自定义的数据类型
int id;
char gender;
char name[20];
char major[20];
student n;//不能定义本身,回引起循环定义的问题
student* next;//可以定义student*型指针变量
}Alice,Bob,stu[N],*p;
可在定义结构体时定义结构体变量,结构体数组或者指针变量,也可按基本数据类型定义
student Alice;
student stu[N];
student *p;
2.结构体元素的访问
定义结构体指针,访问成员用->
定义结构体变量,访问成员用.
按上例子
- 结构体指针
(*p).id
p->id
两者等价
- 结构体变量
Alice.id
3.结构体的初始化
3.1直接赋值
3.1.1逐一直接赋值
对基本数据类型可以逐一直接赋值
Alice.id=1;
Alice.gender='M';
3.1.2 在读入时进行赋值
scanf("%d%c",&Alice.id,&Alice.gender);
常见错误
1.对结构体中数组进行赋值
//char name[20];
int main()
{
Alice.name="Alice";//error
return 0;
}
错误原因:
数组名表示常量,不允许对常量进行赋值操作
改正思路:
方法1.在定义字符数组同时进行赋值
struct student
{
int id;
char gender;
char name[20]="Alice";//ok
char major[20];
}Alice;
方法2.修改类型为string
struct student
{
int id;
char gender;
string name;
char major[20];
}Alice;
然后
int main()
{
Alice.name="Alice";//ok
return 0;
}
方法3.修改赋值方式为strcpy
//char name[20];
int main()
{
strcpy(Alice.name,"Alice");
return 0;
}
2.利用scanf对结构体中string进行赋值
错误原因:
C语言没有string类型,无法直接用scanf读入string类型
scanf:标准输入流,没有缓冲区,需预先分配空间
cin:输入流,使用了缓冲区
如果要使用scanf读入字符串,需要事先申请足够的内存空间
解决思路:
读入:使用resize给string分配内存空间
输出:利用c.str()输出
注意:
1.读入时为&a[0]
2.输出时为a.c_str()
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int main()
{
string a,b;
a.resize(8);
b.resize(8);
scanf("%s%s",&a[0],&b[0]);
printf("%s %s\n",a.c_str(),b.c_str());
return 0;
}
对结构体
注意:
1.在结构体中初始化申请内存空间
2.3与上相同
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int N=1010;
struct student
{
string name;
student()
{
name.resize(8);
}
}stu[N];
int main()
{
scanf("%s%s",&stu[0].name[0],&stu[1].name[0]);
printf("%s %s\n",stu[0].name.c_str(),stu[1].name.c_str());
return 0;
}
3.2构造函数赋值
构造函数:不需要些返回类型,且函数名与结构体相同
3.2.1默认构造函数
注意:没有分号
struct student
{
int id;
char gender;
//默认构造函数
student(){}
};
3.2.2重新定义构造函数
struct student
{
int id;
char gender;
//重定义后,用以对结构体内部变量进行赋值
student(int _id,char _gender)
{
id=_id;
gender=_gender;
}
};
简化
注意:还是没有分号
struct student
{
int id;
char gender;
//重定义后,用以对结构体内部变量进行赋值
student(int _id,char _gender):id(_id),gender(_gender){}
};
3.2.3重定义构造函数后的赋值问题
如果自己重新定义了构造函数,则不能不经初始化就定义结构体变量
//如果改改其实也可以
struct student
{
int id;
char gender;
//用以不初始化就定义结构体变量
student(){}
//只初始化gender
student(_gender):gender(_gender)
//同时初始化id和gender
student(int _id,char _gender):id(_id),gender(_gender){}
};
4 重载运算符实现结构体排序
题目:
https://www.acwing.com/problem/content/description/3378/
- stable_sort写法
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1010;
int n,m;
struct Person
{
string name;
int score;
//定义结构体排序方式
bool operator<(const Person& t) const
{
return score<t.score;
}
bool operator>(const Person & t)const
{
return score>t.score;
}
}q[N];
int main()
{
cin>>n>>m;
for(int i=0;i<n;i++)
cin>>q[i].name>>q[i].score;
if(!m)//逆排序
stable_sort(q,q+n,greater<Person>());
else stable_sort(q,q+n);
for(int i=0;i<n;i++)
cout<<q[i].name<<' '<<q[i].score<<endl;
return 0;
}
- sort写法
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1010;
int n,m;
struct Person
{
string name;
int score;
int id;
bool operator <(const Person& t) const
{
if(score!=t.score) return score<t.score;
return id<t.id;
}
bool operator >(const Person& t) const
{
if(score!=t.score) return score>t.score;
return id<t.id;//注意这里是小于
}
}q[N];
int main()
{
cin>>n>>m;
for(int i=0;i<n;i++)
{
cin>>q[i].name>>q[i].score;
q[i].id=i;
}
if(!m) sort(q,q+n,greater<Person>());
else sort(q,q+n);
for(int i=0;i<n;i++)
cout<<q[i].name<<' '<<q[i].score<<endl;
return 0;
}