这次我们运用链表的基础知识,增删改查,实现对学生系统进行管理,采用的多文件编程模式,接下来介绍一下什么叫做多文件编程。
程序一般分三类文件:
- 头文件( .h )。放置各种声明,用于被文件包含。(头文件的存在是为了联系多个源文件,是源文件之间的接口。)
- 模块文件(.c)。放置一些函数定义,也称为功能模块。
- 主程序文件(.c)。包含main()的文件,程序入口,调用模块文件实现的方法
- 在这里呢要给大家强调一下:在我们包含自己所写的头文件时,用” “(包含的头文件为标准库路径下的,” “为工作路径下的,搜索范围是整个磁盘)
头文件的完整流程描述
#pragma once//避免头文件重复引用
进行头文件引用,把需要运用的都添加进来
#include
#include
#include
首先需要定义一个结构体变量 student,其中包括学生的id,姓名,年龄,专业。
typedef struct Student{
int id;
char name[50];
int age;
char major[50];
struct Student*next;
}Stu;
头文件也需要满足对后续函数的声名定义功能
111
主函数的完整流程描述
菜单printMenu.c的完整流程描述
- 功能:打印操作菜单到控制台,提示用户进行选择。
-
实现:
- 使用printf函数打印菜单的各个部分,包括欢迎语句、各个操作选项以及一个提示用户输入选择的语句。
- 菜单中的每个选项对应一个数字,用户可以通过输入这个数字来选择对应的操作。
-
菜单选项:
- 添加学生:允许用户输入新学生的详细信息(如ID、姓名、年龄和专业),并将这些信息添加到系统中。
- 删除学生:允许用户通过指定学生的ID来删除该学生的信息。
- 更新学生:允许用户修改已存在学生的信息,如姓名、年龄和专业等。
- 搜索学生:允许用户通过学生的ID来搜索并查看该学生的详细信息。
- 退出:退出程序,在退出前,程序应该释放所有动态分配的内存资源,确保没有内存泄漏。
-
用户引导:
- 在打印完菜单后,最后一行”输入您的选择:”用于提示用户输入他们的选择。这是一个重要的交互步骤,它告诉用户该怎么做来选择一个操作。
#include "NodeList.h"
void printMenu(){
printf("n##########学生管理系统#######n");
printf("n请进行选择操作n");
printf("1.添加学生n"):
printf("2.删除学生n"):
prin服务器托管tf("3.更新学生n"):
printf("4.搜索学生n");
printf("5.退出程序n");
printf("n##################n");
}
appendStudent.c的完整流程描述:
createStudent函数
- 功能:动态分配内存以创建一个新的Student结构体实例,并初始化其成员变量。
-
参数:intid:学生的ID。
- char*name:学生的姓名。
- intage:学生的年龄。
- char*major:学生的专业。
- 返回值:返回一个指向新创建的Student实例的指针。如果内存分配失败,则返回NULL。
实现细节:
- 使用malloc函数分配足够的内存来存储一个Student结构体实例。
- 检查malloc是否成功分配了内存。如果没有(即返回NULL),则打印错误消息并返回NULL。
- 使用参数值初始化新创建的Student实例的各个字段。
- 将next指针设置为NULL,因为这个新节点目前不指向任何其他节点。
- 返回新创建的Student实例的指针。
-
#include "NodeList.h" Stu*creatStudent(int id,char *name,int age,char*major){ Stu*student=(Stu*)malloc(sizeof(Stu)); if(student==NULL){ printf("分配空间失败n"); return 0; } student->id=id; strcpy(student->name,name); studnet->age=age; strcpy(student->major,major); student->next=NULL; return student;
appendStudent函数
- 功能:将一个新的Student节点添加到学生链表的末尾。
-
参数:Student**head:指向链表头节点指针的指针。
- 其他参数(id,name,age,major)与createStudent函数相同,用于创建新的学生节点。
- 返回值:无。
实现细节:
- 调用createStudent函数创建一个新的学生节点。
-
如果新节点创建成功,检查链表是否为空(即头指针是否为NULL)。如果链表为空,直接将头指针指向新节点。
-
如果链表不为空,遍历链表找到最后一个节点,然后将其next指针指向新节点,从而将新节点添加到链表末尾。
#include "NodeList.h" void appendStudent(Student**head,int id,char*name,int age,char*major){ Stu*newstu=creatStudent(id,name,age,major); if(newstu==NULL){ newstu=*head; }else{ Stu*temp=*head; while(temp->next!=NULL){ temp=temp->next; } temp->next=newstu; } }
-
如果链表不为空,遍历链表找到最后一个节点,然后将其next指针指向新节点,从而将新节点添加到链表末尾。
deleteStudent.c的完整流程描述:
deleteStudent函数
- 功能:从链表中删除具有指定ID的学生节点。
-
参数:
- Student**head:指向链表头节点指针的指针。使用指针的指针是为了能够在函数内部修改头节点指针的值(例如,当头节点被删除时)。
- intid:要删除的学生的ID。
- 返回值:无。
实现细节:
- 检查链表是否为空:首先检查头指针是否指向NULL,如果是,表示链表为空,打印一条消息并直接返回。
-
删除头节点的情况:
- 如果链表不为空,检查头节点是否就是要删除的节点(通过比较id字段)。
- 如果是,将头指针指向下一个节点(*head=fast->next;),释放原头节点占用的内存,并打印一条删除成功的消息。
-
查找要删除的节点:
- 如果要删除的节点不是头节点,遍历链表寻找匹配的id。使用两个指针fast和slow进行遍历,fast用于指向当前检查的节点,而slow用于记录temp的前一个节点。
- 遍历过程中,如果找到了匹配的节点(fast->id==id),则退出循环准备进行删除操作;如果遍历结束也没有找到匹配的节点,则temp将为NULL。
-
处理学号不存在的情况:
- 如果遍历结束fast为NULL,表示链表中没有找到具有指定ID的学生,打印一条消息说明找不到该学生,并返回。
-
删除找到的节点:
- 如果找到了要删除的节点,将slow->next指向fast->next,这样就从链表中移除了fast指向的节点。
- 然后释放fast节点占用的内存,并打印一条删除成功的消息。
-
#include"NodeList.h" void deleteSudent(Stu**head,int id){ if(*head==NULL){ printf("链表为空n"); return ; }else{ Stu*fast=head,*slow; if((*head)->id=id){ *head=fast->next; printf("删除成功n"); free(fast); }else{ while(fast!=NULL&&fast->id!=id){ slow=fast; fast=fast->next; } if(fast==NULL){ pritnf("没有找到要删除的学生n"); return; } slow-next=fast->next; free(fast); printf("删除成功n"); }
updateStudent.c的完整流程描述:
updateStudent函数
- 功能:更新链表中具有指定ID的学生节点的信息。
-
参数:
- Student*head:链表头节点的指针。
- intid:要更新的学生的ID。
- char*newName:学生的新姓名。
- intnewAge:学生的新年龄。
- char*newMajor:学生的新专业。
- 返回值:无。
实现细节:
-
初始化变量:
- 使用一个临时指针temp来遍历链表,从头节点开始。
- 使用一个标志变量found来记录是否找到了具有指定ID的学生节点。
-
遍历链表:
- 在链表不为空的情况下,遍历每个节点。
- 对于每个节点,检查其ID是否与要更新的学生ID相匹配。
-
更新学生信息:
- 如果找到了匹配的节点,使用strcpy函数将新姓名和新专业复制到该节点的相应字段中,并直接更新年龄字段。
- 更新完成后,打印一条确认消息,并将found标志设置为1,然后跳出循环。
-
处理未找到的情况:
- 如果遍历完整个链表后没有找到匹配的节点(即found仍为0),打印一条错误消息说明找不到具有指定ID的学生。
-
#include "NodeList.h" void updataStudent(Stu*head,int id,char*newName,int newAge,char*newMajor){ Stu*temp=head; int found=0; if(head==NULL)return ; while(temp!=NULL){ if(temp->id=id){ strcpy(temp->name,newName); temp->age=newAge; strcpy(temp->major,newMajor); printf("更新完成n"); found=1; break; } printf("n"); }
searchStudent.c服务器托管的完整流程描述:
searchStudent函数
- 功能:在链表中搜索具有指定ID的学生,并打印该学生的详细信息。
-
参数:
- Student*head:链表头节点的指针。
- intid:要搜索的学生的ID。
- 返回值:无。
实现细节:
-
初始化变量:
- 使用一个临时指针temp来遍历链表,从头节点开始。
- 使用一个标志变量found来记录是否找到了具有指定ID的学生节点。
-
遍历链表:
- 在链表不为空的情况下,遍历每个节点。
- 对于每个节点,检查其ID是否与要搜索的学生ID相匹配。
-
打印学生信息:
- 如果找到了匹配的节点,使用printf函数打印该学生的详细信息(包括ID、姓名、年龄和专业)。
- 打印完成后,将found标志设置为1,并跳出循环。
-
处理未找到的情况:
- 如果遍历完整个链表后没有找到匹配的节点(即found仍为0),打印一条错误消息说明找不到具有指定ID的学生。
#include "NodeList.h"
void searchStudent(Stu*head,int id){
Stu*temp=head;
int found=0;
if(temp=NULL)return;
while(temp!=NULL&&temp->id!=id){
temp=temp->next;
}
if(temp==NULL){
printf("没有找到n");
return;
}
printf("找到了id为%d的学生姓名为%sn",id,name);
printf("找到了id为%d的学生年龄为%dn",id,age);
printf("找到了id为%d的学生专业为%sn",id,major);
}
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
文章目录 2.4_4 死锁的检测和解除 (一)死锁的检测 (二)死锁的解除 总结 2.4_4 死锁的检测和解除 如果系统中既不采取预防死锁的措施,也不采取避免死锁的措施,系统就很可能发生死锁。在这种情况下,系统应当提供两个算法: 1.死锁检测算法:用于…