编写一个学生管理系统程序,用来记录学生的信息(包括姓名、年龄、性别、学号、分数),提供增加、删除、查询学生信息的入口。(C语言) //链表编写一个学生管理系统程序遇到问题,请大神解决。main函数好像不对,然后只能添加1个学生信息,怎么解决?或者大神改进代码,谢谢。
#include <stdio.h> #include <stdlib.h>
//创建节点结构,记录学生的信息 struct student{ char name[20]; //姓名 int age; //年龄 char sex; //性别 int no; //学号 int score; //分数 struct student*next; //指向下一个节点的指针 };
int count; //链表长度,作用是表示链表中节点数量 //create函数创建列表,该函数将会返回链表头指针 struct student *create() { struct student *head=NULL; //初始化链表,头指针为空 struct student *end,*new; //end指向原来尾节点,new指向新创建节点 int count=0; //初始化链表长度 end=new=(struct student*)malloc(sizeof(struct student)); /*使用malloc函数分配内存,end与new都指向第一个分配的内存。malloc函数原型: void*malloc(unsigned int size);功能:是在内存中动态地分配一块size大小的内存空间,返回一个指针,该指针指向分配的内存空间,如果出现错误则返回NULL; 类似函数:calloc函数,其原型:void*calloc(unsigned n,unsigned size),功能:在内存中动态分配n个长度size的连续空间数组,会返回一个指针,该指针指向动态分配的连续内存空间地址, 如果出现错误则返回NULL; */ printf("请输入学生信息(包括姓名、年龄、性别、学号、分数):\n"); scanf("%s",new->name); //姓名 scanf("%d",&new->age); //年龄 scanf("%c",&new->sex); //性别 scanf("%d",&new->no); //学号 scanf("%d",&new->score); //分数 while(new->no!=0){ count++; //表示链表节点增加 //判断新加入节点是否第一次加入节点 if(count==1) { //第一次加入节点时,新节点为首节点也为最后一个节点 new->next=head; //先将新节点指向为空 end=new; //跟踪新加入的节点 head=new; //头指针指向首节点 } else {//加入新节点时链表中已有节点 new->next=NULL; //新节点的指针为空 end->next=new; //原来尾节点指向新节点 end=new; //end指向新节点 } new=(struct student*)malloc(sizeof(struct student)); /*再次分配节点内存空间,然后再次向其中输入数据,通过while循环再次判断输入的数据是否符合节点的要求。当要求不适合时,执行下面的代码,调用free函数将不符合要求的节点空间进行释放*/ scanf("%s",new->name); scanf("%d",&new->age); scanf("%c",&new->sex); scanf("%d",&new->no); scanf("%d",&new->score); } free(new); //释放没有用到的空间 /*free函数原型:void free(void*ptr); 功能:使用由指针ptr指向的内存区,使部分内存区能被其他变量使用。ptr是最近一次调用calloc或malloc函数返回的值。free函数无返回值。*/ return head; } //以上通过动态分配内存空间的方式创建完成链表
void print(struct student*head) //输出链表,查询信息 { struct student*temp; //循环使用临时指针 int n=1; //表示链表中节点的序号 printf("学生管理系统共有%d人\n",count); printf("\n"); temp=head; //指针得到首节点的地址 while(temp!=NULL) { printf("学号%d的学生信息如下:\n",n); //输出学号 printf("姓名:%s\n",temp->name); //输出姓名 printf("年龄:%d\n",temp->age); //输出年龄 printf("性别:%c\n",temp->sex); //输出性别 printf("分数:%d\n",temp->score); //输出分数 printf("\n"); temp=temp->next; //移动临时节点到下一个节点 n++; } } /*print函数将链表数据输出,其参数head表示链表头节点。函数中定义一个临时指针temp用来循环操作,定义整型变量i表示链表节点序号,然后将临时指针temp保存首节点地址。 while语句将所有节点中保存的数据都显示输出,其中每输出一个节点内容后,就移动temp指针指向下一个节点地址,当为最后一个节点时,所拥有的指针指向NULL,循环结束*/
//在链表头节点位置插入节点[有三种插入操作(链表头节点位置插入节点,某个节点位置进行,像创建结构时在链表后面添加节点),思路一样] //向链表中添加节点 struct student *insert(struct student*head) { struct student*new; //指向新分配空间 printf("增加学生信息(包括姓名、年龄、性别、学号、分数):\n"); new=(struct student*)malloc(sizeof(struct student)); //分配内存空间,并返回指向该内存空间的指针 scanf("%s",new->name); scanf("%d",&new->age); scanf("%c",&new->sex); scanf("%d",&new->no); scanf("%d",&new->score); new->next=head; //新节点指针指向原来首节点 head=new; //头指针指向新节点 count++; //增加链表节点数量 return head; //返回头指针 } /*链表的插入需要为插入的链表分配内存,然后向新节点输入数据,这样一个新节点就创建完成了。如果需要将这个节点插入链表中,首先需要将新节点的指针指向原来的首节点,保存首节点的地址,然后将头指针指向新节点,这样就完成节点的连接操作,最后增加链表的节点数量*/
//删除链表节点 void delete(struct student*head,int n) //head表示头节点,n表示要删除节点序号或下标 { int i; //控制循环次数 struct student*temp; //临时指针 struct student*p; //表示要删除节点前的节点 temp=head; //得到头节点 p=temp; printf("删除学号为%d的学生\n",n); for(i=1;i<n;i++) //for循环使temp指向要删除的节点 { p=temp; temp=temp->next; } p->next=temp->next; //连接删除节点两边节点 free(temp); //释放要删除节点的内存空间 count--; //减少链表中节点的元素个数 } /*delete函数传递两个参数,head表示链表头指针,n表示要删除的节点在链表中位置。定义变量i用来控制循环次数,然后定义两个指针,分别表示要删除的节点和这个节点之前的节点。输出一行提示信息表示要进行删除操作,之后利用for语句进行循环操作找到要删除的节点,连接删除节点两边的节点,并使用free函数将temp指向的内存空间进行释放。之后在main函数中添加代码执行删除操作,将链表中第二个节点进行删除*/
int main(){ struct student*head; //定义头节点 head=creaead); //创建节点 head=insert(head); //增加学生信息 delete(head,1); //删除学生信息,例如删除第二个节点操作 print(head); //输出链表 return 0; }
|