自学完c语言尝试写一个学生管理系统
用代码块功能插入代码,请勿粘贴截图
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef struct /*学生类型定义*/
{
int sno; /*学号*/
char sname[8]; /*姓名*/
int score; /*成绩*/
}Student;
typedef struct Node
{
Student data;
struct Node *next;
}LinkList;
LinkList *createTailList () /*以尾插法建立带头节点的单链表*/
{
int x;
LinkList * head=NULL; /遍历找last
do{
printf("输入学生学号\n");
scanf("%d",&x);
if(x!=0) //输出0时结束录入信息
{
LinkList *p=(LinkList*)malloc(sizeof(LinkList));//建立学生信息空间
p->data.sno=x;
printf("输入学生姓名,成绩。\n");
scanf("%s %d",&(p->data.sname),&(p->data.score));
p->next=NULL;
LinkList *last=head;
if(last)
{
while(last->next)
{
last=last->next;
}
last->next=p;
}
else
head=p;
}
}while (x!=0);
return head; //返回头地址
}
//输出函数
void printElem(LinkList *head)
{
LinkList *p=head;//指向head
printf("链表中所有的学生信息如下:\n");
while (p)
{
printf("学号:%d,姓名:%s,成绩:%d\n",p->data.sno,p->data.sname,p->data.score); /*输出p的节点信息*/
p=p->next;//指向下一个
}
}
void menu()//菜单
{
printf("请输入你需要实现的功能\n");
printf("1.显示学生信息\n");
printf("2.修改学生信息\n");
printf("3.插入学生信息\n");
printf("4.删除学生信息\n");
printf("5.退出系统\n");
}
void fix(LinkList *head)//修改学生信息
{
int o1=0;
LinkList *t2=head;
printf("输入被修改的学生的学号\n");
scanf("%d",&o1);
for(t2;t2;t2=t2->next)
{
if(t2->data.sno==o1)
{printf("输入新的姓名与成绩,中间用空格隔开\n");
scanf("%s %d",&(t2->data.sname),&(t2->data.score));//赋值新的数据
printf("修改完成\n");
}
}
}
void myinsert(LinkList *head)//插入节点,不能插入到头节点之前
{
int k1=0;
LinkList *t3=head;
printf("输入被插入的学生的学号\n");
scanf("%d",&k1);
LinkList *n;
LinkList *t31=head->next;
while (t31&&t31->data.sno!=k1)//不能在头节点前插入
{
t3=t31;
t31=t31->next;
}
if(!t31)//坐标
{
printf("无后驱学生,将插入到最后\n");
}
printf("请输入插入学生的学号,姓名,成绩,中间用空格\n");
n=(LinkList *)malloc(sizeof(LinkList));
scanf("%d %s %d",&(n->data.sno),&(n->data.sname),&(n->data.score));
n->next=t31;
t3->next=n;
}
void delete(LinkList *head)//删除节点
{
int w=0;
printf("请输入要删除的学生的学号\n");
scanf("%d",&w);
LinkList *t1;
LinkList *q;
for(q=NULL,t1=head;t1;q=t1,t1=t1->next)// t1会指向要删除的节点;
{
if(t1->data.sno==w)//删除的不是头节点
{if(q)
{
q->next=t1->next;
}
else
{
head=t1->next;//要删除的是头节点
}
printf("删除完毕\n");
free (t1);
t1=NULL;
break;
}
}
printElem(head) ;
}
int main(int argc,char *argv[ ])
{
int a;
printf("请输入学生信息\n");
LinkList *head=createTailList(*head ) ;
system("pause");//暂停 输入其他案件继续执行后续的代码
system("CLS");//清屏 清除之前的输入提示等等 使页面干净
menu();
while(1)
{
printf("请选择所需功能:");
scanf("%d",&a);
switch(a)
{
case 1:
printElem(head);//输出
menu();
break;
case 2:
fix(head);//修改
menu();
break;
case 3:
myinsert(head);//插入
menu();
break;
case 4:
delete(head);//删除
menu();
break;
case 5://退出系统
exit(0);
break;
}
}
}
在之前写过这个一模一样的,只不过没用函数,而是一长串的写下来,删除模块可以删除掉头结点的,而且不会出现垃圾值,但是用了函数后,删除头节点是不行的,我已经释放了头结点的内存,但那段内存仍然被垃圾值填充,并没有消失。我试着在删除完节点的函数中继续添加了一个输出链表的函数,这个输出是正常的,但是你在菜单页面让他再次输出,就会出现头节点并没有消失,而是被垃圾值填充。
我的解答思路和尝试过的方法 :我尝试过在释放内存后,让指向头结点的指针指向null,但仍然无济于事。
我想要达到的结果 :头节点可以正常删除,直接消失,而不是出现垃圾值。