写在前面:这是我学习c语言的最后一个部分,学完链表将进入下一部分的学习.
链表是c语言和数据结构链接的一个部分
本文主要利用链表的知识设计了学生管理系统
包括:
- 链表的建立
- 链表元素的删除
- 链表内数据的修改
- 链表冒泡排序的实现
- 链表循环打印
下面是源代码:
StudentSystem.h 头文件代码
#include <stdio.h>//标准的输入输出函数库
#include<stdlib.h>//标准库,包含malloc函数
#include <conio.h>//_getch函数
#define stuinfo stu.info //宏定义文件名字
//建立学生信息的结构体
typedef struct _student_
{
int StudentNum;//学生的学号
float Score;//学生的成绩
char Name[20];
}Student; //将 struct _student_定义为student 后续方便使用
typedef struct _node_ //定义链表结点的结构
{
Student stu; //学生的信息
struct _node_* next; //指向下一个结点的指针
}Node;
void SaveStudent(Node* head) {
FILE* file = fopen("./stuinfo", "w"); // 1.令fopen函数的返回值为一个文件指针 2. fopen ./为打开 stuinfo为stu.info的宏定义 "w"表示覆盖写入
if (file == NULL)
{
printf("打开文件失败!");
return; //直接返回结束函数
}
Node* move = head->next; //将遍历指针指向头结点的第一个结点
while (move != NULL)//判断条件为部位空
{
if (fwrite(&move->stu, sizeof(Student), 1, file) != 1)//fwrite(存入信息的地址,信息的大小,写入的个数,写入的位置),写入成功则为1,失败则不为1
{
printf("保存%s的信息时出现错误", move->stu.Name);
}
move = move->next;//遍历
}
fclose(file);//打开文件也要积分关闭文件
}
void LoadStudent(Node* head)
{
FILE* file = fopen("./stuinfo","r");
if (!file)//如果不存在文件
{
printf("暂无学生信息!\n");
return;
}
//创建一个结点接收之前的文件
Node* fresh = malloc(sizeof(Node));
fresh->next = NULL;//初始化指针
Node* move = head;//创建一个遍历指针
while (fread(&fresh->stu,sizeof(Student),1,file)==1)
{
move->next = fresh;
move = fresh;
fresh = malloc(sizeof(Node));
fresh->next = NULL;
}
free(fresh
);
}
void interface(void)//定义选择界面函数
{
printf("-----------------------------\n");
printf("\t学生管理系统 \n");
printf("-----------------------------\n");
printf("\t功能选择列表 \n");
printf("-----------------------------\n");
printf("\t1.录入学生信息\n");
printf("\t2.打印学生信息\n");
printf("\t3.统计学生信息\n");
printf("\t4.查找学生信息\n");
printf("\t5.修改学生信息\n");
printf("\t6.删除学生信息\n");
printf("\t7.按成绩排序\n");
printf("\t8.退出系统\n");
};
void InputStudentInformation(Node* head)//定义输入函数
{
Node* move = head; //建立一个指针,指向头结点,用于链表的遍历
Node* fresh = malloc(sizeof(Node)); // 创建一个新的结点
fresh->next = NULL;//先将结点的指针初始化为空(养成好习惯)
//输入学生的信息
printf("请输入学生的学号:");
scanf("%d",&fresh->stu.StudentNum);
printf("请输入学生的名字:");
scanf("%s", fresh->stu.Name);//name是一个数组,数组名是数组的首地址不要取地址符
printf("请输入学生的成绩:");
scanf("%f", &fresh->stu.Score);//成绩是一个浮点数,用%f
while (move->next != NULL)//如果指针指向不为空
{
move = move->next;
}
move->next = fresh;//将新建立的结点,添加到链表的尾部
SaveStudent(head);
}
void PrintStudetInformation(Node* head)
{
Node* move = head->next;//令遍历指针等于头结点指针
while (move != NULL) {
printf("学号:%d 姓名:%s 成绩:%f \n",move->stu.StudentNum,move->stu.Name,move->stu.Score);
move = move->next;
}
}
void CountStudent(Node* head)
{
int count = 0;
Node* move = head;
while (move->next != NULL)
{
count++;
move = move->next;
}
printf("共有 %d 位学生录入系统\n",count);
}
void FindStudent(Node* head)
{
Node* move = head;
int studentnum = 0;//也要记得初始化
printf("请输入需要查找学生的学号:");
scanf("%d",&studentnum);
while (move->next!=NULL)
{
if (move->stu.StudentNum==studentnum)
{
printf("学号为;%d 的学生的姓名为:%s 成绩为:%f ",move->stu.StudentNum,move->stu.Name,move->stu.Score);
return;
}
move = move->next;
}
printf("查无此人!\n");
}
void ModifyStudentInfomation(Node* head)
{
int stunum = 0;
printf("请输入需要修改学生的学号:");
scanf("%d",&stunum);
Node* move = head;
while (move != NULL)
{
if (move->stu.StudentNum==stunum)
{
printf("请重新输入该学生的成绩:");
scanf("%f",&move->stu.Score);//修改学生信息,记得要取地址符号
printf("请重新输入该学生的名字:");
scanf("%s", move->stu.Name);//修改学生信息
break;
}
move = move->next;
}
if (move == NULL)//循环结束也没有找到学号
printf("查无此人!\n");
SaveStudent(head);
}
void Deletstudent(Node* head)
{
int stunum = 0;
printf("请输入需要删除学生的学号:");
scanf("%d", &stunum);
Node* move = head;
while (move->next!=NULL)
{
if (stunum==move->next->stu.StudentNum)
{
Node* go = move->next;
move->next = go->next;
free(go);
go = NULL;
SaveStudent(head);
printf("删除学生成功!\n");
return;
}
move = move->next;
}
if (move->next == NULL)
printf("查无此人!\n");
}
void SortStudent(Node* head)
{
Node*move = NULL;
Node*keep = NULL;
for (Node* turn = head->next; turn->next !=NULL; turn=turn->next)
{
for (move = head->next; move->next!= keep ; move = move->next)
{
if (move->stu.Score < move->next->stu.Score)//这里得指向要搞清楚
{
Student change = move->stu;
move->stu = move->next->stu;
move->next->stu = change;
}
}
keep = move;
}
PrintStudetInformation(head);
}
main.c 主函数代码
#include"StudentSystem.h"
//void interface(void);
//void InputStudentInformation();
//void PrintStudetInformation();
//void CountStudent();
//void FindStudent();
int main()
{
Node* head = malloc(sizeof(Node)); //创建链表的头结点,利用malloc函数构建动态内存
head->next = NULL; //指针初始化,头结点指向空,NULL是大写的
LoadStudent(head);
char c = '0';
while (c != '8')
{
interface();
c = _getch(); //利用这个函数不需要键入回车就能进行键入
switch (c)
{
case '1': //录入学生信息
InputStudentInformation(head);//引用函数
break;
case '2': //打印学生信息
PrintStudetInformation(head);//调用打印函数
break;
case '3': //统计学生人数
CountStudent(head);
break;
case '4': //查找学生信息
FindStudent(head);
break;
case '5': //修改学生信息
ModifyStudentInfomation(head);
break;
case '6': //删除学生信息
Deletstudent(head);
break;
case '7': //按成绩排序
SortStudent(head);
break;
case '8': //退出系统
exit(0);
break;
default:
break;
}
system("pause");//等待用户的下一步操作
system("cls");//清空终端窗口的信息
}
}