结构体的大杂烩

这块一直有些没整明白,抽空把能想到的系统总结一下

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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值