基于链式存储的学生成绩管理系统的设计 c语言

题目

基于链式存储的学生成绩管理系统的设计 急!!! 15C
1,建立一张学生成绩表,每个学生包含“学号、姓名、性别、语文、数学、英语、平均分”
2,将该表中所有信息按平均分降序排列
3,按学号查找某学生所有成绩
4,插入某学生成绩在合适位置,不影响原来排序
(用链表实现)

前言

上面是问答的原题,默默表示现在都没有接到他的回复,可怜俺的代码啊!所有这篇博文出现了<_<

问题分析

首先一看到这个:学生包含“学号、姓名、性别、语文、数学、英语、平均分”就应该想到结构体(c语言里面),这是结构体存在的意义之一,就是存储不同数据类型的一个集合,这是数组解决不了的事情。然后是存储信息,就是链表的基本操作,增,删,查,改,当然还有销毁咯(基本操作不知道的可以查一下,很多,我也就不加追述了)。不过这里好像没有这么多要求,看上去好像感觉到,只是没有基本操作那么单纯而已。
为了规范化和模块化,个人还是建议写一个头文件和一个.c文件,用于主程序的调用。让主程序显得更加简洁。

按照他的要求1,建立一张学生成绩表,每个学生包含“学号、姓名、性别、语文、数学、英语、平均分”,这也就确定了结构体的成员,学号可以是unsigned int,语文、数学、英语、平均分这些可以是float(老师心情不好扣你10分<_<),也可以是unsigned float之类的。姓名,性别肯定是字符串咯。至于平均分没必要算,你可以写一个函数,自动算出,然后存进去,这样就简单方便。

至于第二点要求,将该表中所有信息按平均分降序排列就更简单了,因为增加一个结点就是一个数的插入,你可以刚开始就排好,类似于选择排序,输入一个就给你插在相应的位置,这样就不需要后期重新排序。

至于3,按学号查找某学生所有成绩,写一个学号匹配函数(也就是基本操作查)就可以了,4,插入某学生成绩在合适位置,不影响原来排序,当第二点满足时这点就满足了。

代码块

1.LIST.h头文件

#ifndef __LIST_H__
#define __LIST_H__
struct node
{
	unsigned int student_num;//存储学号
	char name[20];//姓名
	char gender[6];//性别:man或者woman
	float chinese;
	float math;
	float english;
	float average;//存储平均成绩
	struct node * next;
};
typedef struct node Node;//结点的别名
struct hnode
{
	Node * first;//第一个结点的地址
	unsigned class_num;//这个班级(表)的人数
};
typedef struct hnode Hnode;//头结点的类型
/*
	Hnode * create_list();
	创建一个空链表,返回链表的头结点
*/
Hnode * create_list();

/*
	Hnode * increase_element(Hnode *h,Node *element);
	增加一个学生的信息
	@h:表的头结点,表示哪一个表
	@element:增加的学生的信息
	返回其头结点
*/
Hnode * increase_element(Hnode *h,Node *element);

/*
	void average_score(Node *element);
	求@element学生的平均成绩,并且存入其@element信息中
	@element:表示学生的信息
*/
void average_score(Node *element);

/*
	void destory_list(Hnode *h);
	销毁一张表或者一个班级的学生信息
	@h:表的头结点或者表示某一个班级的头结点
*/
void destory_list(Hnode *h);

/*
	void traverse_list(Hnode*h);
	打印@h这张表的信息
	
*/
void traverse_list(Hnode*h);

/*
	Node * search_list(Hnode *h,unsigned int num);
	查找@num学号的学生信息
	返回其学生的信息结构体地址
*/
Node * search_list(Hnode *h,unsigned int num);




#endif

2.LIST.c

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"list.h"

Hnode * create_list()
{
	Hnode * h=(Hnode *)malloc(sizeof(Hnode));
	h->class_num=0;
	h->first=NULL;
	return h;
}

Hnode * increase_element(Hnode *h,Node *element)
{
	if(NULL==element)//增加的成员信息为空,则取消增加
	{
		return h;
	}
	Node *p=(Node *)malloc(sizeof(Node));
	Node *q=NULL;
	Node *before=NULL;
	int i=0;
	p->average=element->average;
	p->chinese=element->chinese;
	p->english=element->english;
	p->math=element->math;
	p->next=NULL;
	p->student_num=element->student_num;
	strcpy(p->gender,element->gender);//注意字符串不支持直接赋值
	strcpy(p->name,element->name);//注意字符串不支持直接赋值
	printf("succeed\n");//表示信息添加成功进入
	//现在部分编译器直接struct直接整体赋值
	if(NULL==h->first)//如果是增加第一个学生
	{
		h->first=p;
		h->class_num++;//班级人数加一
		return h;//返回头结点
	}
	else
	{
		q=h->first;
		while(q)//查找第一个比新增成员平均成绩低的
		{
			if(p->average<q->average)//没有找到
			{
				before=q;//保存找到的前一个的地址
				q=q->next;//继续下一个
				i++;//记录比新增成员大的成员个数
			}
			else
			{
				break;//找到,跳出循环
			}
		}
		if(0==i)//当新增成员信息比所有人的平均成绩高时
		{
			h->first=p;//插入最前面
			p->next=q;//连接原来的信息
			h->class_num++;
			return h;
		}
		else//不是最前的时候的连接
		{
			before->next=p;
			p->next=q;
			h->class_num++;
			return h;
		}
	}
	return h;
}
void average_score(Node *element)
{
	element->average=(element->chinese+element->english+element->math)/3;
}
Node * search_list(Hnode *h,unsigned int num)
{
	if(NULL==h->first)//空表无法查询
	{
		return NULL;
	}
	Node *end=h->first;
	while(end)//从头开始查找
	{
		if(num!=end->student_num)
		{
			end=end->next;
		}
		else
		{
			break;
		}
	}
	return end;
}
void destory_list(Hnode *h)
{
	if(NULL==h->first)//空表销毁
	{
		free(h);
		return;
	}
	Node *p=h->first;
	while(p)//销毁结点
	{
		p=h->first->next;
		free(h->first);
		h->first=p;
	}
	free(h);//销毁头结点
}
void traverse_list(Hnode*h)
{
	Node *p=h->first;
	while(p)
	{
		printf("%u %s %s %f %f %f %f\n",p->student_num,p->name,p->gender,p->chinese,p->math,p->english,p->average);	
		p=p->next;
	}
}

主函数main.c
主函数仅仅只是本人用于测试写的,可以根据自己需求调用相应子程序进行修改,或者完善

#include<stdio.h>
#include"list.h"
int main()
{
	Hnode *h=create_list();
	Node student;
	Node* search=NULL;
	int k=0;
	printf("请分别输入学生的学号 姓名 性别 语文成绩 数学成绩 英语成绩\n");
	scanf("%d%s%s%f%f%f",&student.student_num,student.name,student.gender,&student.chinese,&student.math,&student.english);
	average_score(&student);
	h=increase_element(h,&student);
	while(1)
	{
		printf("请问是否输入完成,完成为1,继续为0\n");
		scanf("%d",&k);
		if(1==k)
		{
			break;
		}
		scanf("%u%s%s%f%f%f",&student.student_num,student.name,student.gender,&student.chinese,&student.math,&student.english);
		average_score(&student);
		h=increase_element(h,&student);
	}
	printf("这是输入信息\n");
	traverse_list(h);
	while(1)
	{
		printf("请问是否需要查找,不需要为-1,需要请输入学号\n");
		scanf("%d",&k);
		if(-1==k)
		{
			break;
		}
		search=search_list(h,k);
		if(NULL==search)
		{
			printf("没有这个学生\n");
			break;
		}
		printf("查找的学生的学号是:%u\n",search->student_num);
		printf("查找的学生为:%s\n",search->name);
		printf("性别为:%s\n",search->gender);
		printf("语文成绩为:%f 数学成绩为:%f 英语成绩为:%f\n",search->chinese,search->math,search->english);
		printf("平均成绩是:%f\n",search->average);
	}
	destory_list(h);
	return 0;
}

结果

运行环境:gcc
编辑环境:sources insight
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

结语

代码尽量写了注释(当然一些简单的地方也就忽略了),如果有什么疑问或者其他,欢迎私信或者留言,如果对你有什么帮助,可以点一个赞,谢谢!

  • 7
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
学习【数据结构课程】中线性表知识,自己动手做的【学生信息 管理 系统】。 目的:重在功能实现,思考探索。 编程语言:C IDE:VC++6.0 基础功能:增、删、查、改。 【扩展功能: 1.数据的保存、读取; 2.账号的登入、登出; 3.对数据敏感操作的日志记录; 4.对查询结果的简单数量统计。】 缺陷:没有排序功能,统计能不够强大,对非法或刁难的数据处理效果微弱。 (感兴趣的朋友可以试着填补上述缺陷) 【水平有限,代码仅作参考。 有不足之处,还望指出,非常感谢。】 附录: 1.学生信息 类型: typedef struct { char id[11]; /*学号,12入学年份,34学院,56专业,78班级,90班内号数*/ char name[11]; /*姓名,仅考虑由字母组成的名字*/ int sex; /*性别,男1,女0*/ char headTeacher[11]; /*班主任*/ int entranceScore; /*入学成绩*/ char birthday[9]; /*xxxx年xx月xx日*/ char Tel[12]; /*联系电话,11位*/ char homeAddress[21]; /*家庭地址*/ } stuData; 2.文件目录: head.c linklist.c linkqueue.c list.txt log.c logData.txt login.c main.c stu.c stuData.txt user.c userData.txt 基础:C语言知识,特别强调:指针和链表的知识.txt 学生信息系统_流程图_粗糙.png 提示:阅读代码可以从head.c或main.c开始;运行程序从main.c开始,登陆账号在userData.txt中设置.txt 效果图1_登陆账号.png 效果图2_登陆账号2.png 效果图3_功能选择.png 效果图4_浏览学生信息.png 效果图5_查询学生信息.png 效果图6_退出查询学生信息.png 效果图7_退出账号.png 效果图8_退出系统.png 【完毕】
### 回答1: 要查询选修了两门以上课程的学生学号和平均成绩,需要进行以下步骤: 1. 首先,需要查询选修了哪些课程的学生,可以使用如下SQL语句: SELECT 学生学号, COUNT(*) AS 选修课程数 FROM 选课表 GROUP BY 学生学号 HAVING COUNT(*) >= 2; 这条语句会返回选修了两门以上课程的学生学号和他们选修的课程数。 2. 接下来,需要查询这些学生的平均成绩,可以使用如下SQL语句: SELECT 学生学号, AVG(成绩) AS 平均成绩 FROM 选课表 WHERE 学生学号 IN ( SELECT 学生学号 FROM 选课表 GROUP BY 学生学号 HAVING COUNT(*) >= 2 ) GROUP BY 学生学号; 这条语句会返回选修了两门以上课程的学生学号和他们的平均成绩。 综合起来,可以使用如下SQL语句查询选修了两门以上课程的学生学号和平均成绩: SELECT 学生学号, AVG(成绩) AS 平均成绩 FROM 选课表 WHERE 学生学号 IN ( SELECT 学生学号 FROM 选课表 GROUP BY 学生学号 HAVING COUNT(*) >= 2 ) GROUP BY 学生学号; ### 回答2: 要查询选修了两门以上课程的学生学号和平均成绩,需要按照以下步骤进行: 1. 首先,需要查询选修了哪些课程的学生存在。可以使用如下SQL语句来查找所有选修了两门以上课程的学生: ``` SELECT student_id FROM course_list GROUP BY student_id HAVING COUNT(course_id) >= 2; ``` 这里,course_list是一个包含学生选修情况的表,其中student_id表示学生的学号,course_id表示所选修的课程编号。通过GROUP BY子句和HAVING子句,可以筛选出选修了两门以上课程的学生学号。这个查询结果将作为下一步查询的过滤条件。 2. 接着,需要查询每个符合条件的学生的平均成绩。可以使用如下SQL语句来实现: ``` SELECT student_id, AVG(score) AS avg_score FROM enrollment WHERE student_id IN ( SELECT student_id FROM course_list GROUP BY student_id HAVING COUNT(course_id) >= 2 ) GROUP BY student_id; ``` 这里,enrollment是一个包含学生选课成绩信息的表,其中student_id表示学生的学号,score表示选修课程的成绩。通过使用子查询来过滤出选修了两门以上课程的学生列表,然后在enrollment表中根据这个列表筛选出对应的选课成绩信息。最后,通过GROUP BY子句来按学生学号进行合并,并计算每个学生的平均成绩。 综上所述,以上两个SQL语句可以实现查询选修了两门以上课程的学生学号和平均成绩。需要注意的是,具体的表结构和数据根据实际情况进行相应的调整和修改。 ### 回答3: 要查询选修了两门以上课程的学生学号和平均成绩,需要先了解一些基本概念。一门课程的成绩可以用分数来表示,而不同学生选修的课程数量是不同的。要计算学生的平均成绩,需要将各门课程的成绩相加,再除以课程数量。因此,要查询选修了两门以上课程的学生学号和平均成绩,需要通过数据库查询语句来实现。 首先,需要确定查询的数据表。假设我们有以下数据表: | 学生 | 学号 | 课程 | 成绩 | |------|------|------|------| | 张三 | 001 | 数学 | 80 | | 张三 | 001 | 英语 | 90 | | 李四 | 002 | 数学 | 85 | | 李四 | 002 | 物理 | 75 | | 王五 | 003 | 数学 | 90 | | 王五 | 003 | 英语 | 95 | | 赵六 | 004 | 数学 | 70 | | 赵六 | 004 | 生物 | 80 | 其中,“学生”表示学生姓名,“学号”表示学生的唯一标识符,“课程”表示选修的课程名称,“成绩”表示该门课程的得分。 接下来,可以使用查询语句来查询选修了两门以上课程的学生学号和平均成绩。具体查询语句如下: ``` SELECT 学号, AVG(成绩) AS 平均成绩 FROM 数据表 GROUP BY 学号 HAVING COUNT(*) >= 2; ``` 在该查询语句中,“SELECT”表示要查询的字段,“AVG”表示求平均值的函数,“AS”表示给平均成绩起一个别名,“FROM”表示要查询的数据表,“GROUP BY”表示按照学号进行分组,“HAVING”表示对分组后的数据进行筛选,“COUNT(*)”表示统计选修课程数量。 通过以上查询语句,可以得到选修了两门以上课程的学生学号和平均成绩,结果如下: | 学号 | 平均成绩 | |------|----------| | 001 | 85 | | 002 | 80 | | 003 | 92.5 | 因此,在该数据表中,选修了两门以上课程的学生有张三、李四和王五,他们的平均成绩分别为85、80和92.5。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

@矛盾综合体

感觉有帮助可以点个赞哦

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

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

打赏作者

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

抵扣说明:

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

余额充值