> 文章列表 > 【头歌C语言程序设计】结构体解答

【头歌C语言程序设计】结构体解答

【头歌C语言程序设计】结构体解答

写在前面

这道题总体来说还是偏难的,如果只看代码比较难以理解,当结构体的文章发出后,就有许多小伙伴问我这个问题,我开始意识到,可能我对这道题所作的解答还不够(不装了😁,根本没有解答),所以我又回头看了看这道题,下面是我的一些个人理解,希望对各位小伙伴有帮助。


没看懂题目?

在这里插入图片描述

目的就是统计生日相同的学生,并输出他们的信息。

在这里插入图片描述

  • 看输入部分。第一行是5,接下来5行,每一行都是学生学号、生日,这就很好办,不是难点,一个for循环就能搞定,**但是以何种形式存储才能在要处理时方便一些?**相信大家一定一头雾水,大家继续往下看…

  • 看输出部分。第一行是生日+两个学号,第二行也是同样的生日+两个学号,这里就稍微有些棘手了,**怎样让生日相同的学生学号一并输出?**我们先按下不表


不清楚结构体?

看完了输入和输出部分,就剩中间最难的部分了,别急,先做好准备工作,我们来回答上面的第一个问题:以何种形式存储较好。
答:我们考的就是结构体当然就以结构题的形式来存储了,先声明这样一个的结构体类型,并同时定义一个结构体数组stu[50]可以用来存放50个学生的信息,我称其为输入数组

在这里插入图片描述

第二个结构体类型又是怎样一回事呢?

在这里插入图片描述

这时我们就可以回答上面的第二个问题:怎样让生日相同的学生学号一并输出?

  • 答:相信你能猜到char ids[50][6]的作用了,没错这就是用来存生日相同的学生的五位学号+'\\0’的。例如,1月10日有两位学生生日相同,将他们的学号分别存入bir[0].ids[0]和bir[0].ids[1]中,第二个结构体数组,我称之为输出数组。

  • 学的好的话,bir[50]={ 0 },就会知道我们把初始的50个数组中的nums全部赋初值为0,

  • 这里面的nums相当于一个计数器,用来记录生日相同的学生有几个,如果有生日相同的学生,num就+1。


不理解变量含义?

n 用来存储学生个数
i , j 主要用于循环变量
k 用来记录输出数组中生日不相同的学生数量,例如输出数组中有四名学生,有三名生日都相同,则k就等于2

搞不懂执行情况?

好了,卖了这么多的关子,相信你已经对题目比较了解了。接下来看中间部分

在这里插入图片描述

结合实际例子可能比较容易理解,就按照题目给出的示例来解释。示例中n=5,所以就会执行5次大循环。

5
00001 1 10
00002 2 24
00003 1 10
00004 12 21
00005 12 21

  • 第一次大循环。 j = 0、k = 0,所以第一个小循环( for循环 )就不会执行了,继续下面看if(j == k),这个循环就可以执行,此时就会把第一个学生的信息( 00001 1 10 )由输入数组(stu[0])存进输出数组(bir[0]),顺带将num置为1,k置为1,第一次大循环结束。

  • 第二次大循环。 j = 0、k = 1,则进入第一个小循环( for循环 )且仅执行一次,判断第二位同学的生日( 00002 2 24 )和输入数组(stu[0])中学生生日不同。继续执行下面代码,此时 j = 1、k = 1,if(j == k)符合条件,此时就会把第二个学生的信息( 00002 2 24 )由输入数组存进输出数组中的第二个位置上( bir[1] ),顺带将第二个位置上的num置为1( bir[1].num = 1),k置为2,第二次大循环结束。

  • 第三次大循环,j = 0、k = 2,则进入第一个小循环( for循环 ),将第三位同学的生日( 00003 1 10)和输出数组中的两位同学生日( bir[0]和bir[1] )比较,判断出和输出数组中第一位同学生日相同( bir[0] ),就直接退出第一个小循环。此时 j = 0、k = 2,所以if(j == k)就不符合条件,执行else语句,将第三名同学( stu[2] )的学号存进输出数组( bir[0].ids[1],注意bir[0].ids[0]存的是第一位同学的学号 ),并将bir[0].num置为2。

  • 第四次大循环, j = 0、k = 2,则进入第一个小循环,判断输入数组中第四位( stu[3] )和输出数组中学生生日都不同,此时 j = 2、k = 2,所以if(j == k)符合条件,就把第四位同学的生日信息由输入数组存入输出数组(bir[3])中,并将num置为1,k置为3。第四次大循环结束。

  • 第五次大循环,j=0、k=3,则进入第一个小循环,将第五位同学的生日( 00003 1 10)和输出数组中的三位同学生日比较,判断和第三位同学( bir[2] )生日相同,就直接退出第一个小循环。此时j = 3、k = 3,if(j == k)符合条件,此时就会把第五个学生的信息( 00005 12 21 )由输入数组存进输出数组中的第三个位置上,顺带将第三个位置上的num置为2,k置为4,第五次大循环结束。


完整代码


#include <iostream>
using namespace std;
#include<string.h>
/**********   Begin   **********/
struct stuinfo //储存输入学生的信息,简称输入数组
{char id[6];int month;int day;
}stu[50];  //给50的空间是因为0<=n<50struct birs //储存输出学生的信息,简称输出数组
{int nums;int month;int day;char ids[50][6];
}bir[50]={0};void Count()
{int n,i,j,k=0;scanf("%d",&n);//输入n个学生信息for(i=0;i<n;i++)scanf("%s%d%d",stu[i].id,&stu[i].month,&stu[i].day);//处理for(i=0;i<n;i++){//主要判断 输入数组 中的学生和 输出数组 中的每一个学生生日是否相同for(j=0;j<k;j++){if(bir[j].month == stu[i].month && bir[j].day == stu[i].day)break;}//将不同生日的学生分开存放if(j==k){bir[k].day = stu[i].day;bir[k].month = stu[i].month;strcpy(bir[k].ids[0],stu[i].id);bir[k].nums = 1;k++;}//将相同生日的学生放在一起else{strcpy(bir[j].ids[bir[j].nums],stu[i].id);bir[j].nums++;}}//输出for(i=0;i<k;i++){//只输出同一天生日学生数>=2的数组if(bir[i].nums > 1){printf("%d %d ",bir[i].month,bir[i].day);for(j=0;j<bir[i].nums;j++)printf("%s ",bir[i].ids[j]);printf("\\n");}}
}
/**********   End   **********/

总结

通过对这道题的解析,相信大家已经都理解了。当然这只是其中一种解题思路,可能还有更好的方法,欢迎大家在评论区里分享。最后,希望大家在遇到困难时不要放弃,多想想,多尝试尝试!