写3个函数建立链表, 删除结点, 插入结点,输出3名学生的数据记录

问题遇到的现象和发生背景

写3个函数建立链表, 删除结点, 插入结点,输出3名学生的数据记录

用代码块功能插入代码,请勿粘贴截图

#pragma warning(disable : 4996) 
#include
#include
#include

#define N 3                          //3位学生
#define LEN (sizeof(struct Student))

typedef struct Student
{
    long number;
    float score;
    struct Student* next;
}student;


int main()
{
    student* ahead;
    student* creat(int n);                                        //创建声明
    student* del(student * head, long n);             //删除声明
    student* insert(student * head, student * new_Node);                        //插入声明
    void print(student * head);                    //输出声明
    void clear(student * head);        //释放声明

    ahead = creat(N);
    print(ahead);

    long t;
    printf("please enter the student number that needs to be deleted:");   //输入想要删除的学号
    scanf("%ld", &t);
    printf("\n");
    del(ahead, t);
    print(ahead);

    printf("please enter the student number you want to add:");     //输入想要插入的学号,成绩
    student* new_Node;
    new_Node = (student*)malloc(LEN);
    if (new_Node == NULL)
    {
        printf("out of memory, the request failed!");   //内存不足,申请失败
        exit(-1);          //程序异常退出
    }
    memset(new_Node, 0, LEN);
    scanf("%ld %f", &new_Node->number, &new_Node->score);
    printf("\n");
    ahead = insert(ahead, new_Node);
    print(ahead);
    return 0;
}


student* creat(int n)         //尾插法创建链表
{
    int i;
    student* head, * node, * end;
    head = (student*)malloc(LEN);        //给头结点申请空间
    if (head == NULL)
    {
        printf("out of memory, the request failed!");   //内存不足,申请失败
        exit(-1);          //程序异常退出
    }
    memset(head, 0, LEN);
    end = head;            //首尾地址一致,空表
    printf("enter data records for 3 students:\n");
    for (i = 0; i < n; i++)
    {
        node = (student*)malloc(LEN);        //给普通结点申请空间
        if (node == NULL)
        {
            printf("out of memory, the request failed!");   //内存不足,申请失败
            exit(-1);       //程序异常退出
        }
        memset(node, 0, LEN);        //清零
        end->next = node;        //前驱结点的指针域存放着当前结点的地址
        end = node;         //指向后驱结点
        scanf("%ld %f", &node->number, &node->score);
    }
    end->next = NULL;            //尾结点地址为空
    return head;         //返回第一个结点的地址
}


student* del(student* head,long n)    //删除结点
{
    student* p;
     if (head->next == NULL)     //链表有头结点,则头结点的指针域为空就表示链表为空
     {
         printf("the table is empty!\n");       //空表
         return head;
     }
     else
     {
         for (; head != NULL; head = head->next)    //p不能指向空,所以当p指向尾结点后结束循环
         {
             if (head->next->number == n)         //p的后驱结点中数据域中number的值
             {
                 p = head->next;
                 head->next = head->next->next;       //当前p的指针域存放下下个结点的地址,跳过了p的后驱结点
                 free(p);      //释放p的后驱结点的内存空间
                 return head;        //返回第一个结点的地址
             }

             else
             {
                 printf("the node could not be found!\n");       //找不到该结点
             }
         }
     }
}


student* insert(student* head, student* new_Node)      //插入结点
 {
    student* p;
    for (p = head; head != NULL ; p = p->next)     //如果新插入结点的学生号 > 某个结点的学生号,并且不能是尾结点,因为尾结点后面不能插入结点
    {
        if (new_Node->number > p->number)
        {
            new_Node->next = p->next;        //插入结点的指针域存放p的后驱结点
            p->next = new_Node;            //p的指针域存放新插入结点的地址
            return head;     //返回第一个结点的地址
        }
    }
 }
 

void print(student* head)    //输出链表
{
    student* p;
    printf("Now, the data of these students are :\n");
    for (p = head->next; p != NULL; p = p->next)
    {
        printf("%5ld\t%5.2f\n", p->number, p->score);
    }
}

void clear(student* head)       //释放内存
{
    student* p;
    while (head != NULL)      //循环条件:链表不为空,当链表结点内存释放完,链表为空时,循环结束
    {
        p = head;           //p指向头结点
        head = head->next;         //head指向下一个结点
        free(p);              
        p = NULL;
    }
}

```)
###### 运行结果及报错内容 

```c
enter data records for 3 students:
10101 90.0
10103 98.0
10105 87.0
Now, the data of these students are :
10101   90.00
10103   98.00
10105   87.00
please enter the student number that needs to be deleted:10103

the node could not be found!    //出错
Now, the data of these students are :
10101   90.00
10105   87.00
please enter the student number you want to add:10107 12

Now, the data of these students are :
10107   12.00                     //出错,10107应该最下面的
10101   90.00
10105   87.00

警告 C4715 “insert”: 不是所有的控件路径都返回值
警告 C4715 “del”: 不是所有的控件路径都返回值

student* del(student* head,long n) 删除结点函数,student* insert(student* head, student* new_Node) 插入结点函数,两个函数做了修改,改动处见注释,供参考:

#pragma warning(disable : 4996)
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define N 3   //3位学生
#define LEN (sizeof(struct Student))
typedef struct Student
{
    long number;
    float score;
    struct Student* next;
}student;
int main()
{
    student* ahead;
    student* creat(int n);   //创建声明
    student* del(student * head, long n);  //删除声明
    student* insert(student * head, student * new_Node); //插入声明
    void print(student * head);        //输出声明
    void clear(student * head);        //释放声明
    ahead = creat(N);
    print(ahead);
    long t;
    printf("please enter the student number that needs to be deleted:"); //输入想要删除的学号
    scanf("%ld", &t);
    printf("\n");
    del(ahead, t);
    print(ahead);
    printf("please enter the student number you want to add:");//输入想要插入的学号,成绩
    student* new_Node;
    new_Node = (student*)malloc(LEN);
    if (new_Node == NULL)
    {
        printf("out of memory, the request failed!");   //内存不足,申请失败
        exit(-1);          //程序异常退出
    }
    memset(new_Node, 0, LEN);
    scanf("%ld %f", &new_Node->number, &new_Node->score);
    printf("\n");
    ahead = insert(ahead, new_Node);
    print(ahead);
    return 0;
}
student* creat(int n)         //尾插法创建链表
{
    int i;
    student* head, * node, * end;
    head = (student*)malloc(LEN);        //给头结点申请空间
    if (head == NULL)
    {
        printf("out of memory, the request failed!");   //内存不足,申请失败
        exit(-1);          //程序异常退出
    }
    memset(head, 0, LEN);
    end = head;            //首尾地址一致,空表
    printf("enter data records for 3 students:\n");
    for (i = 0; i < n; i++)
    {
        node = (student*)malloc(LEN);        //给普通结点申请空间
        if (node == NULL)
        {
            printf("out of memory, the request failed!");   //内存不足,申请失败
            exit(-1);       //程序异常退出
        }
        memset(node, 0, LEN); //清零
        end->next = node;   //前驱结点的指针域存放着当前结点的地址
        end = node;         //指向后驱结点
        scanf("%ld %f", &node->number, &node->score);
    }
    end->next = NULL;            //尾结点地址为空
    return head;         //返回第一个结点的地址
}
student* del(student* head,long n)    //删除结点
{
    student* p;
     if (head->next == NULL)     //链表有头结点,则头结点的指针域为空就表示链表为空
     {
         printf("the table is empty!\n");       //空表
         return head;
     }
     else
     {
         for (; head->next != NULL; head = head->next)//p不能指向空,所以当p指向尾结点后结束循环
         //for (; head != NULL; head = head->next)  修改
         {
             if (head->next->number == n)         //p的后驱结点中数据域中number的值
             {
                 p = head->next;
                 head->next = head->next->next;       //当前p的指针域存放下下个结点的地址,跳过了p的后驱结点
                 free(p);      //释放p的后驱结点的内存空间
                 return head;  //返回第一个结点的地址
             }
         }  //修改
            //else  修改
            //{     修改
         if (!head->next) //修改
             printf("the node could not be found!\n");//找不到该结点
            //} 修改
     }
}
student* insert(student* head, student* new_Node)      //插入结点
 {
    student* p;
    for (p = head; p->next != NULL ; p = p->next)//如果新插入结点的学生号 > 某个结点的学生号,并且不能是尾结点,因为尾结点后面不能插入结点
    //for (p = head; head != NULL ; p = p->next)//修改
    {
        if (new_Node->number < p->next->number) //修改  if (new_Node->number > p->number)
        {
            break;                              //修改
        }
    } //修改
    new_Node->next = p->next;//插入结点的指针域存放p的后驱结点  //修改
    p->next = new_Node;  //p的指针域存放新插入结点的地址        //修改
    return head;     //返回第一个结点的地址
 }
void print(student* head)    //输出链表
{
    student* p;
    printf("Now, the data of these students are :\n");
    for (p = head->next; p != NULL; p = p->next)
    {
        printf("%5ld\t%5.2f\n", p->number, p->score);
    }
}
void clear(student* head)   //释放内存
{
    student* p;
    while (head != NULL)    //循环条件:链表不为空,当链表结点内存释放完,链表为空时,循环结束
    {
        p = head;           //p指向头结点
        head = head->next;  //head指向下一个结点
        free(p);
        p = NULL;
    }
}