使用C语言实现学生信息管理系统

前言

在我们实现学生信息管理系统的过程中,我们几乎会使用到C语言最常用最重要的知识,对于刚学习完C语言的同学来说是一次很好的巩固机会,其中还牵扯到数据结果中链表的插入和删除内容。

实现学生信息管理系统

文件的创建与使用

·对于要实现一个大项目而言,我们要把函数进行分装,分装到头文件中,在.c文件中使用

#include"//头文件名"

另外对于定义函数时还可以专门的放在另一个.c文件中,便于维护,在这个小项目中当然不用这样做,不过为了养成好习惯,建议大家这样做。

头文件的使用

#include<stdio.h>
#include<stdlib.h>
#include<conio.h>

 创建存储学生信息结构体和节点信息结构体

//学生信息
typedef struct _Student
{
	int stuNum;
	char name[30];
	int source;
}Student;

//节点信息
typedef struct _Node
{
	Student student;
	struct _Node* next;
}Node;

 系统界面的初始化

//初始化界面
void welcome()
{
	printf("**********************************\n");
	printf("*\t学生成绩管理系统\t*\n");
	printf("**********************************\n");
	printf("*\t请选择功能列表\t\t*\n");
	printf("**********************************\n");
	printf("*\t1.录入学生信息\t\t*\n");
	printf("*\t2.打印学生信息\t\t*\n");
	printf("*\t3.统计学生信息\t\t*\n");
	printf("*\t4.查找学生信息\t\t*\n");
	printf("*\t5.修改学生信息\t\t*\n");
	printf("*\t6.删除学生信息\t\t*\n");
	printf("*\t7.按成绩排序\t\t*\n");
	printf("*\t8.退出系统\t\t*\n");
	printf("**********************************\n");
}

输入学生信息

//输入学生信息
void inputStudent(Node* head)
{
	Node* fresh = (Node*)malloc(sizeof(Node));
	fresh->next = NULL;
	printf("请输入学生的学号、姓名、成绩:");
	scanf("%d %s %d", &fresh->student.stuNum, fresh->student.name, &fresh->student.source);
	Node* move = head;
	while (move->next != NULL)
	{
		move = move->next;
	}
	//将学生信息插入链表尾部
	move->next = fresh;
	saveStudent(head);//学生信息持久化函数(自定义)
} 

打印学生信息

//打印学生信息
void printStudent(Node* head)
{
	Node* move = head->next;
	while (move != NULL)
	{
		printf("学号:%d 姓名:%s 成绩:%d\n", move->student.stuNum, move->student.name, move->student.source);
		move = move->next;
	}
	//暂停程序
	system("pause");
//清空控制台
	system("cls");
}

统计学生人数

//统计学生人数
void countStudent(Node* head)
{
	welcome();

	int count = 0;
	Node* move = head->next;
	while (move != NULL)
	{
		count++;
		move = move->next;
	}
	printf("学生的总人数为%d", count);
	//暂停程序
	system("pause");
//清空控制台
	system("cls");
}

查找学生信息

void findStudent(Node* head)
{
	welcome();

	int stuNum;
	printf("\n请输入要查找的学生的学号:");
	scanf("%d", &stuNum);
	Node* move = head->next;
	while (move != NULL)
	{
		if (stuNum == move->student.stuNum)
		{
			printf("学号:%d 姓名:%s 成绩:%d\n", move->student.stuNum, move->student.name, move->student.source);
			return;
		}
		move = move->next;
	}
	printf("未找到学生信息\n");
	//暂停程序
	system("pause");
//清空控制台
	system("cls");
}

学生信息持久化

//学生信息持久化
void saveStudent(Node* head)
{
	FILE* file = fopen("./stu.info", "w");
	if (file == NULL)
	{
		printf("文件打开失败\n");
		return;
	}
	Node* move = head->next;
	while (move != NULL)
	{
		if ((fwrite(&move->student, sizeof(Student), 1, file)) != 1)
		{
			printf("写入失败\n");
			return;
		}
		move = move->next;
	}
	fclose(file);
}

读取学生信息

//读取学生信息
void loadStudent(Node* head)
{
	FILE* file = fopen("./stu.info", "r");
	if (!file)
	{
		printf("没有学生文件,跳过读取\n");
		return;
	}
	Node* fresh = (Node*)malloc(sizeof(Node));
	fresh->next = NULL;
	Node* move = head;
	while (fread(&fresh->student, sizeof(Student), 1, file) == 1)
	{
		move->next = fresh;
		move = fresh;
		fresh = (Node*)malloc(sizeof(Node));
		fresh->next = NULL;
	}
	free(fresh);
	fclose(file);
	printf("读取成功\n");
}

修改学生信息

//学生信息修改
void modifyStudent(Node* head)
{
	welcome();

	printf("请输入要修改信息学生的学号:");
	int stuNum;
	scanf("%d", &stuNum);
	Node* move = head->next;
	while (move != NULL)
	{
		if (stuNum == move->student.stuNum)
		{
			printf("请输入学生的姓名、成绩\n");
			scanf("%s %d", move->student.name, &move->student.source);
			saveStudent(head);
			printf("修改成功\n");
			return;
		}
		move = move->next;
		//暂停程序
		system("pause");
//清空控制台
		system("cls");
	}
	printf("未找到学生信息\n");
}

删除学生信息

//删除学生信息
void deleteStudent(Node* head)
{
	welcome();

	int stuNum;

	printf("请输入要删除学生信息的学号");
	scanf("%d", &stuNum);
	
	Node* move = head;
	while (move->next != NULL)
	{
		if (move->student.stuNum == stuNum)
		{
			Node* tmp = move->next;//把要删除的数据的保存的节点存放在一个临时节点中,防止前后节点丢失
			move->next = move->next->next;
			free(tmp);
			tmp = NULL;
			saveStudent(head);
			printf("删除成功\n");
			return;
		}
		move = move->next;
	}
	//暂停程序
	system("pause");
//清空控制台
	system("cls");
}

链表的删除操作

由于没学到数据结构,这个只是我浅薄的认识。

对学生成绩进行排序

//对学生成绩排序
void sortStudent(Node* head)
{
	welcome();

	Node* move = NULL;
	Node* save = NULL;
	for (Node* turn = head->next; turn->next != NULL; turn = turn->next)
	{
		for (Node* move = head->next; move->next != save; move = move->next)
		{
			if (move->student.source > move->next->student.source)
			{
				Student temp = move->student;
				move->student = move->next->student;
				move->next->student = temp;
			}
		}
		save = move;//下一趟排序不用再次比较已经排序好的最大值

	}
	printStudent(head);
	//暂停程序
	system("pause");
//清空控制台
	system("cls");
}

冒泡排序

冒泡排序是在一趟一趟的过程中对相邻元素比较大小进行排序,例如我们进行升序排序,在每一趟的过程中,会把这一趟的最大元素排到最前面,进而进行下一趟排序,周而复始知道最后一趟的相邻元素大小符合升序排列。

在其中排序的过程中,由于在每一趟中我们会把最大数排列在随后,所以在以后的每一次排序中都不必要对上一趟排序后结果的最大值进行比较,例如:

对于这个算法的实现请看下面:

退出系统以及在main函数中调用这些函数:

int main()
{
	Node* head = (Node*)malloc(sizeof(Node));
	head->next = NULL;
	loadStudent(head);
	welcome();

	while(1)
	{

		char c = _getch();
		switch (c)
		{
			case '1': inputStudent(head);
			break;
		case '2':printStudent(head);
			break;
		case '3':countStudent(head);
			break;
		case '4':findStudent(head);
			break;
		case '5':modifyStudent(head);
			break;
		case '6':deleteStudent(head);
			break;
		case '7':sortStudent(head);
			break;
		case '8':printf("\n欢迎下次使用,bye-");
			     exit(0);
			break;
		default:printf("请重新输入\n");
			break;
		}
	}
	
	return 0;
}


退出系统

总结

对于前面的函数实现而言,大多数代码的思路是相同的,对于学生信息的删除和成绩排序需要我们重点理解,愿与诸君共勉!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/661349.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【国产中颖】SH79F9202U单片机驱动LCD段码液晶学习笔记

1. 引言 因新公司之前液晶数显表产品单片机一直用的是 C51单片机(SH79F9202U9)&#xff0c;本人之前没有接触过这款单片机&#xff0c;为了维护老产品不得不重新研究研究这款单片机。 10位ADC LCD的增强型8051微控制器 SH79F9202是一种高速高效率8051可兼容单片机。在同样振…

TH方程学习(1)

一、背景介绍 根据CW方程的学习&#xff0c;CW方程的限制条件为圆轨道&#xff0c;不考虑摄动&#xff0c;二者距离相对较小。TH方程则可以将物体间的相对运动推广到椭圆轨道的二体运动模型&#xff0c;本部分将结合STK的仿真功能&#xff0c;联合考察TH方程的有用性&#xff…

19 - grace数据处理 - 补充 - 地下水储量计算过程分解 - 冰后回弹(GIA)改正

19 - grace数据处理 - 补充 - 地下水储量计算过程分解 - 冰后回弹(GIA)改正 0 引言1 gia数据处理过程0 引言 由水量平衡方程可以将地下水储量的计算过程分解为3个部分,第一部分计算陆地水储量变化、第二部分计算地表水储量变化、第三部分计算冰后回弹改正、第四部分计算地下…

学习笔记——数据通信基础——数据通信网络(基本概念)

数据通信网络基本概念 网络通信&#xff1a;是指终端设备之间通过计算机网络进行的通信。 数据通信网络(Data Communication Network)&#xff1a;由 路由器、交换机、防火墙、无线控制器、无线接入点&#xff0c;以及个人电脑、网络打印机&#xff0c;服务器等设备构成的通信…

canfd与can2.0关系

canfd是can2.0的升级版&#xff0c; 支持canfd的设备就支持can2.0&#xff0c;但can2.0的设备不支持canfd 参考 是选CAN接口卡还是CANFD接口卡_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1Hh411K7Zn/?spm_id_from333.999.0.0 哪些STM32有CANFD外设 STM32G0, STM…

Django 做migrations时出错,解决方案

在做migrations的时候&#xff0c;偶尔会出现出错。 在已有数据的表中新增字段时&#xff0c;会弹出下面的信息 运行这个命令时 python manage.py makemigrationsTracking file by folder pattern: migrations It is impossible to add a non-nullable field ‘example’ to …

软件架构设计属性之一:功能性属性浅析

引言 软件架构设计属性中的功能性属性是评估软件架构是否满足其预定功能需求的关键指标。功能性属性确保软件能够执行其设计中的任务&#xff0c;并提供所需的服务。以下是对软件架构设计中功能性属性的浅析&#xff1a; 一、定义 功能性属性是指软件系统所具备的功能特性&a…

flutter开发实战-类似微博帖子列表及下拉刷新上拉加载效果

flutter开发实战-类似微博帖子列表及下拉刷新上拉加载效果 在之前处理类似微博帖子列表及下拉刷新上拉加载效果&#xff0c;刷新使用的是EasyRefresh 一、引入EasyRefresh与likeButton 在工程的pubspec.yaml中引入插件 # 下拉刷新、上拉更多easy_refresh: ^3.3.21pull_to_re…

MySQL建库

删除数据库 新建数据库 右键-新建数据库 字符集选中utf8(支持中文) 修改字符集 右键--数据库的属性 将字符集支持的数量变少可以修改

算法的时间与空间复杂度

算法是指用来操作数据、解决程序问题的一种方法。对于同一问题&#xff0c;使用不同的算法&#xff0c;也许最终结果是一样的&#xff0c;但在过程中消耗的资源和时间却会有很大的区别。 那我们该如何去衡量不同算法之间的优劣呢&#xff1f;主要还是从算法所占用的【时间】和…

最新!2023年台湾10米DEM地形瓦片数据

上次更新谷歌倾斜摄影转换生成OSGB瓦片V1.1版本&#xff0c;使用该版本生产了台北、台中、桃园三个地方的倾斜摄影OSGB数据&#xff0c;在OSGB可视化软件中进行展示&#xff0c;可视化效果和加载效率俱佳。已经很久没更新地形瓦片数据&#xff0c;主要是热点地区的原始数据没有…

6.S081的Lab学习——Lab5: xv6 lazy page allocation

文章目录 前言一、Eliminate allocation from sbrk() (easy)解析&#xff1a; 二、Lazy allocation (moderate)解析&#xff1a; 三、Lazytests and Usertests (moderate)解析&#xff1a; 总结 前言 一个本硕双非的小菜鸡&#xff0c;备战24年秋招。打算尝试6.S081&#xff0…

HTTP Digest Access Authentication Schema

HTTP Digest Access Authentication Schema 背景介绍ChallengeResponse摘要计算流程总结参考 背景 本文内容大多基于网上其他参考文章及资料整理后所得&#xff0c;并非原创&#xff0c;目的是为了需要时方便查看。 介绍 HTTP Digest Access Authentication Schema&#xff…

STL库--stack

目录 stack的定义 stack容器内元素的访问 stack常用函数实例解析 stack的常见用途 stack的定义 其定义的写法和其他STL容器相同&#xff0c;typename可以任意基本类型或容器&#xff1a; stack<typename> name; stack容器内元素的访问 由于栈本身就是一种后进先出…

Java Class类简介

一、类图&#xff1a; 二、基本介绍&#xff1a; 1. Class也是类&#xff0c;因此也继承了Object类。 2. Class类的对象不是new出来的&#xff0c;是系统创建的。 类加载器ClassLoader有个方法LoadClass()&#xff0c;将某个类对应的Class对象生成在堆中。 通过调试可以发现&am…

代码随想录-Day23

669. 修剪二叉搜索树 方法一&#xff1a;递归 class Solution {public TreeNode trimBST(TreeNode root, int low, int high) {if (root null) {return null;}if (root.val < low) {return trimBST(root.right, low, high);} else if (root.val > high) {return trimBS…

python基础-数据结构-leetcode刷题必看-queue---队列-python的底层构建

文章目录 队列双端队列 deque底层存储deque接口1. __init__(self, iterable: Iterable[_T], maxlen: int | None None) -> None2. append(self, __x: _T) -> None3. appendleft(self, __x: _T) -> None4. copy(self) -> Self5. count(self, __x: _T) -> int6. …

GoFly框架快速新增接口/上手写代码

拿到一个新框架大家可能无从下手&#xff0c;因为你对框架设计思路、结构不了解&#xff0c;从而产生恐惧&#xff0c;所以我们框架是通过简单可视化界面安装&#xff0c;安装后即可看到效果&#xff0c;然后点击先点点看各个功能&#xff0c;看现有的功能是怎么写的&#xff0…

怎样清理Mac存储空间 苹果电脑内存不够用怎么办 苹果电脑内存满了怎么清理

在使用 Mac 电脑的过程中&#xff0c;用户经常会遇到磁盘空间不足的困扰&#xff0c;这时候就需要寻找有效的方法来清理苹果电脑内存了。 清理Mac存储空间可以通过多种方法进行&#xff0c;以确保你的Mac能够高效运行并释放宝贵的存储空间。以下是一些有效的清理和优化方法&am…

swift 自定义扫码功能

使用功能​​​​​​​ 1. 调用扫码功能&#xff08;扫描二维码/条形码、图片识别二维码/条形码、生成二维码/条形码&#xff09; 2. 自定义扫码界面UI&#xff08;继承式自定义修改样式&#xff0c;完全自定义调用封装组件&#xff09; 3. 生成二维码/条形码 源码地址&#x…