C++结构体基础之结构体排序和学生信息分析

本文详细介绍结构体的基础概念、排序及信息解析的应用实例,包括学生信息管理、书籍排序及学号解析,适合初学者掌握结构体的使用技巧。

目录

前言:

一,结构体基础

1,题目

2,代码

3,分析

二,结构体排序

1,代码

2,分析

三,键盘输入学号,分析学生信息

1,代码

2,分析

前言:

dfs(depth first search深度优先搜索)的博客写到一半,遇到了迷宫,涉及到结构体,所以回来复习一下

一,结构体基础

1,题目

请帮老师写一个程序,要求存储本年级100个学生的姓名,学号,语文,英语,数学三门课的成绩,并根据语文成绩递减顺序,输出所有学生信息

这里简化为4个学生,结果是一样的

2,代码

#include<iostream>
#include<stdio.h>//scanf(), printf()
using namespace std;
const int n = 4, m = 20;//整型常量

typedef struct student
{
    char name[m];//成员名name
    int number;//成员名number
    float chinese;
    float english;
    float math;
}stu;

int main()
{
    stu s[n], temp;//变量名s1, 变量名temp
    //for循环中++i等价于i++, 且++i更节省空间速度更快
    //变量名.成员名访问结构体元素
    for(int i = 0; i < n; ++i)
        scanf("%s %d %f %f %f", s[i].name, &s[i].number,
              &s[i].chinese, &s[i].english, &s[i].math);
    printf("\n");
    for(int i = 0; i < n; ++i)
    {
        int Max = i;//记录语文成绩最大值位置
        for(int j = i+1; j < n; ++j)
            if(s[j].chinese > s[Max].chinese)
            {
                temp = s[j];//因为s[j]为结构体变量,所以temp也得是
                s[j] = s[Max];
                s[Max] = temp;//选择排序,最大值放前面
            }
    }
    for(int i = 0; i < n; ++i)
        printf("%s %d %.2f %.2f %.2f\n", s[i].name, s[i].number,
              s[i].chinese, s[i].english, s[i].math);

    return 0;
}

输入输出

QQ  4  67  89  78
Ten 2  99  12  62
albion 1 77 66 55
apex   3 69 51 100

Ten 2 99.00 12.00 62.00
albion 1 77.00 66.00 55.00
apex 3 69.00 51.00 100.00
QQ 4 67.00 89.00 78.00

3,分析

0,关于代码第21行scanf中s[i].name前没有取地址符

因为C++中字符串名和数组名都表示其地址,所以输入时不需要加"&"

而单独的字符、整型变量等不能直接表示地址,所以要加取地址符

1,结构体把它的所有成员看作一个整体,这些成员可以是不同类型的变量,比如int q, char a[], float n, char c,也可以是结构体,struct是关键字

2,结构体的定义

注意,结构体本身也是一种数据类型,类似int, char等,不过是自定义的罢了

struct 结构名
{
    类型名1 成员名1;
    类型名2 成员名2;
    类型名3 成员名3;
};
或者
typedef struct 结构名
{
    类型名1 成员名1;
    类型名2 成员名2;
    类型名3 成员名3;
}stu;

typedef是类型定义符,eg:把struct student定义成stu,后面再定义变量就省事点

stu是随便编的,不和什么类型名等冲突就行

{}后的";"不要漏

3,结构体变量的定义

//以题目代码为例
typedef struct student
{
    ...
    ...
}stu;
stu s[20];

或者

//以题目代码为例
typedef struct student
{
    ...
    ...
};
 struct student s[20];

两者等价

4,同类型的结构变量可以彼此赋值

比如stu s1, s2 = {"apex", 2, 99, 88, 77};

//结构student需要提供姓名,学号,三科成绩,所以变量s2的初始化对应5个数据

s1 = s2;

s1, s2都属于student(题目代码中的结构体类型名)这种类型,所以类型相同

5,结构变量中成员的引用(访问) 

结构变量名.结构成员名,这里的 "."可以读作"的",比如s.name读作"s变量的name成员"

6,结构变量初始化和赋值例子 

代码

#include<iostream>
#include<stdio.h>//scanf(), printf()
using namespace std;

struct person
{
    char name[20];
    long long id;
    float salary;
};

int main()
{//下面结构变量初始化
    struct person pr1 = {"apex", 20222010085, 12500};
    struct person pr2;
    pr2 = pr1; //结构体变量互相赋值

    printf("%s\t%lld\t%.1f", pr2.name, pr2.id, pr2.salary);

    return 0;
}

输出

apex    20222010085     12500.0

👀 👀 👀去MOOC找找二和三的原题目 👀 👀 👀 

二,结构体排序

1,代码

#include<iostream>
#include<algorithm>//sort()
#include<iomanip> //setprecision(), setiosflags(ios::fixed)
#include<string.h> //strcmp(s1,s2),比较两字符串大小,s1 > s2输出正数
using namespace std;

struct book
    {
        char name[50];//书名
        float price;//价格
        int classification;//类别编号
    };

bool cmp(book x, book y)
    {
        if(x.price != y.price)
            return x.price < y.price;
        return strcmp(x.name,y.name) > 0;//仿函数,类似lambda的功能
    }//return strcmp(x.name,y.name) < 0结合strcmp()函数可知按从小到大返回
//比较器函数和结构体最好一起放主函数外,不能在一个函数中定义另一个函数

int main()
{
    struct book s[101];
    int n;
    cin>>n;//n本书

    for(int i = 0; i < n; i++)
    {
        cin>>s[i].name>>s[i].price>>s[i].classification;
        //变量名.成员名访问结构体的成员
    }
    sort(s,s+n,cmp);//sort(起始地址,结束地址,比较器)
    for(int i = 0; i < n; i++)
        cout<<s[i].name<<","<<setprecision(2)<<setiosflags(ios::fixed)
            <<s[i].price<<","<<s[i].classification<<endl;

    return 0;
}

输入输出

4
Englishbook 25 1
Chinese     35 1
CHINESE     35 1
Indian      15 1
Indian,15.00,1
Englishbook,25.00,1
Chinese,35.00,1
CHINESE,35.00,1

2,分析:

1,结构体变量初始化和赋值还可以直接从键盘输入

 for(int i = 0; i < n; i++)
    {
        cin>>s[i].name>>s[i].price>>s[i].classification;

    }

2,代码中的bool函数最后,

if(x.price != y.price)

        return x.price < y.price;

意思是如果两本书价格不一样,按从小到大的顺序输出

如果价格一样,按字符串从大到小输出

return strcmp(x.name,y.name) > 0

三,键盘输入学号,分析学生信息

1,代码

#include<iostream>
#include<stdio.h> //scanf,printf
using namespace std;

typedef struct student//定义struct student学生这种结构
{
    char grade[5];
    char department[3];//都是字符数组类型
    char major[3];//都比实际长度多一位,以便存放字符串结束符'\0'
    char cclass[3];//共五个成员
    char number[4];
}student;

int main()
{
    char number[14];//13 + 1 == 14, 留一个位置给结束符'\0'
    student s;//定义了student结构的变量s
    int i;
    scanf("%s", number, 13);//读入字符串要指明读入多少个字符,这里13个
    //数组名number表示数组首地址,所以前面不需要取地址符'&'
    for(i = 0; i < 4; i++) //0,1,2,3,将number中四个数据复制到grade成员中
        s.grade[i] = number[i];//变量名.成员名访问成员
    s.grade[i] = '\0';// i = 4

    s.department[0] = number[i++];//第5个数据, i = 4
    s.department[1] = number[i++];
    s.department[2] = '\0';

    s.major[0] = number[i++];
    s.major[1] = number[i++];
    s.major[2] = '\0';

    s.cclass[0] = number[i++];
    s.cclass[1] = number[i++];
    s.cclass[2] = '\0';

    s.number[0] = number[i++];
    s.number[1] = number[i++];
    s.number[2] = number[i++];//第13个数据,i = 12
    s.number[3] = '\0';//长度14

    printf("学院:%s;专业:%s;年级:%s;班:%s;学号:%s\n",
           s.department, s.major, s.grade, s.cclass, s.number);
    //以%s的形式按字符串输出
    return 0;
}

输入输出

2022020104325
学院:02;专业:01;年级:2022;班:04;学号:325

2,分析:

(请看注释)

1,该结构体共5个成员,年级,学院,专业,班级,学号

2,结构体中的成员变量名,与非结构体变量没有关系,可以相同,所以有个成员变量名number[4],还有个主函数中的变量名number[14],

所以可以和成员名重复,但不能结构体类型名重复,比如本题代码中的student

3,根据代码,输入按年级,学院,专业,班级,学号的顺序,输出按学院,专业,年级,班级,学号的顺序

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

千帐灯无此声

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

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

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

打赏作者

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

抵扣说明:

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

余额充值