(注意事项都已经在代码中标注)
1.链表相关函数的头文件
#define  _CRT_SECURE_NO_WARNINGS
 #pragma once
 #include <stdio.h>
 #include <stdlib.h>
 #include <assert.h>
 #include <errno.h>
 #include <string.h>
 typedef int datatype;
 typedef struct slistnode {
     datatype data;
     struct slistnode* node;
 }slnode;
 void menu();
 void slprint(slnode* slist1);//展示
 void slpush_back(slnode** slist1, datatype x);//尾增
 void slpush_front(slnode** slist1, datatype x);//头增
 slnode* sl_find(slnode* slist1, datatype x);//查找
void slpop_back(slnode** slist1);//尾删
 void slpop_front(slnode** slist1);//头删
 void slpush_onin(slnode** slist1, slnode* pos, datatype x);//在指定位置前面增,这里使用的是找前驱,但是实际上可以改该位置的数据,再生成一个新的结点使用该位置的data连接上去,就不需要找前驱
 void slpop_onin(slnode** slist1, slnode* pos);//删除指定位置的数据
2.具体实现的函数
#include "slist.h"
 void menu() {
     printf("******************************\n");
     printf("***1.头插            2.尾插***\n");
     printf("***3.头删            4.尾删***\n");
     printf("***5.在指定数前面增加一个数***\n");
     printf("***6.删除指定第一个数      ***\n");
     printf("***0.exit                  ***\n");
     printf("******************************\n");
}
 void slprint(slnode* slist1) {
     
     if (slist1 == NULL) {
         printf("该链表暂时并没有任何的结点,无法打印\n");
     }
     else{
         printf("开始打印该链表中的内容:");
         while (slist1 != NULL) {
             
             printf("%d->", slist1->data);
             slist1 = slist1->node;
         }
         printf("NULL");
         printf("\n打印结束\n");
         printf("-----------------------------\n");
     }
}
 slnode* buynewnode(datatype x) {
     slnode* newnode = (slnode*)malloc(sizeof(slnode));
     if (newnode != NULL) {
         newnode->data = x;
         newnode->node = NULL;
         return newnode;
     }
     else {
         printf("buynewnode err:%s\n", strerror(errno));
         return NULL;
     }
 }
 void slpush_back(slnode** slist1, datatype x) {
     slnode* newnode = buynewnode(x);
     if (*slist1 == NULL) {
         *slist1 = newnode;//这里就是尾删为什么使用二级指针的原因
     }
     else {
         slnode* slist_tmp = *slist1;
         while (slist_tmp->node != NULL) {
             slist_tmp = slist_tmp->node;
         }
         slist_tmp->node =newnode;
     }
 }
 void slpush_front(slnode** slist1, datatype x) {
     slnode* newnode = buynewnode(x);
     if (*slist1 == NULL) {
         *slist1 = newnode;//这里就是头插为什么使用二级指针的原因
     }
     else {
         newnode->node = *slist1;
         *slist1 = newnode;
     }
 }
 slnode* sl_find(slnode* slist1, datatype x) {
     if (slist1 == NULL) {
         printf("该链表暂时为空\n");
         return NULL;
     }
     else{
         while (slist1->data != x) {
             slist1 = slist1->node;
         }
         return slist1;
     
     }
     
 }
 void slpop_back(slnode** slist1) {
     slnode* prev = *slist1;
     slnode* slist1_tmp = *slist1;
     if (slist1_tmp == NULL) {
         return;
     }
     else if(slist1_tmp->node==NULL){
         free(*slist1);
         *slist1 = NULL;//这里的分类讨论要注意,为什么在尾删也需要二级指针,因为在这里需要直接让他指向空;头指针发生了变化
     }
     else {
         while (slist1_tmp->node != NULL) {
             prev = slist1_tmp;
             slist1_tmp = slist1_tmp->node;
        }
         prev->node = NULL;
         free(slist1_tmp);//这里没有分类讨论的话,前驱跟找尾部的指针会指向同一个,会有特殊的地方
    }
 }
 void slpop_front(slnode** slist1) {
     slnode* flag_slist1 = *slist1;
     if (*slist1 == NULL) {
         return;
     }
     else {
         (*slist1) = (*slist1)->node;//头删很显然就是需要使用二级指针的
         free(flag_slist1);
         flag_slist1 = NULL;
     }
}
 void slpush_onin(slnode** slist1, slnode *pos,datatype x) {//找到的该数后在前面增加一个数
     if (*slist1==pos) {
         slpush_front(slist1, x);
     }
     else{
         slnode* slist1_tmp = *slist1;
         while (slist1_tmp->node != pos) {
             slist1_tmp = slist1_tmp->node;
         }
         slnode* newnode = buynewnode(x);
         slist1_tmp->node = newnode;
         newnode->node = pos;
     }
 }
 void slpop_onin(slnode** slist1, slnode* pos) {//删除指定位置的的数,上下这两个都是在一个的时候会有特殊情况,就是相当于头删和头增
     if (*slist1 == pos) {
         slpop_front(slist1);
     }
     else {
         slnode* slist1_tmp = *slist1;
         while (slist1_tmp->node != pos) {
             slist1_tmp = slist1_tmp->node;
         }
         slist1_tmp->node = pos->node;
         free(pos);
         
     }
 }
3.主函数
#include "slist.h"
 int main() {
     int input = 0;
     slnode* slist1 = NULL;
     do {
         menu();
         printf("请输入你想要进行的操作数\n");
         scanf("%d", &input);
         switch (input) {
         case 1:
             printf("请输入你要头插的数\n");
             int n = 0;
             scanf("%d", &n);
             slpush_front(&slist1, n);
             slprint(slist1);
             break;
         case 2:
             printf("请输入你要尾插的数\n");
             n = 0;
             scanf("%d", &n);
             slpush_back(&slist1, n);
             slprint(slist1);
             break;
         case 3:
             printf("正在进行头删\n");
             slpop_front(&slist1);
             slprint(slist1);
             printf("头删结束\n");
             break;
         case 4:
             printf("正在进行尾删\n");
             slpop_back(&slist1);
             slprint(slist1);
             printf("尾删结束\n");
             break;
         case 5:
             printf("正在进行指定数前加\n");
             printf("请输入指定数\n");
             int x = 0;
             scanf("%d", &x);
             slnode* pos = sl_find(slist1,x);
             if (pos) {
                 printf("可以进行前加,正在进行前加\n");
                 printf("请输入你要加入的数\n");
                 scanf("%d", &n);
                 slpush_onin(&slist1, pos, n);
            }
             else
                 printf("没有找到指定的数\n");
             slprint(slist1);
             break;
         
         case 6:
             printf("正在进行指定数删除\n");
             printf("请输入指定数\n");
             x = 0;
             scanf("%d", &x);
             pos = sl_find(slist1, x);
             if (pos) {
                 printf("正在进行删除\n");
                 
                 
                 slpop_onin(&slist1, pos);
            }
             else
                 printf("没有找到指定的数\n");
             slprint(slist1);
             break;
         case 0:
             printf("正在退出程序\n");
             break;
         default:
             printf("您的输入存在错误\n");
         }
     
     } while (input);
     
     return 0;
}
 //注意事项,当在指定位置进行插入的时候,只有一个相当于头插,不能直接使用原来的方法,否则会报错
 //同理删指定位置,就相当于头删