c语言单链表删除功能问题

最近在学习单链表的操作,增删查改这些,自己改善了一下代码,感觉其他的都没问题,就是删除函数这里有问题。我单独剔出来了

#include
#include 
typedef struct link{
 int value;
 struct link *next;
}Link;
Link* init_list(void);//初始化 
void display(Link *p);//链表输出
Link* del(Link *p,int location);//删除元素

int main()
{
 int cut;
 Link *q=init_list();
 printf("初始化链表为\n");
 display(q);
 printf("请输入要删除的数的位置:\n");
 scanf("%d",&cut); 
 del(q,cut);
 display(q);
 return 0;
}

Link* init_list(void)
{

 re_input:
;
 int x=0;
 int mask=0,count=0;
 Link* head=NULL;
 Link *p=(Link*)malloc(sizeof(Link*));
 head=p;
 printf("请输入数据(输入-1结束)\n");
 do
 {
  mask=scanf("%d",&x);
  if(x!=-1&&mask!=0)
  {
  Link *a=(Link*)malloc(sizeof(Link*));
  a->value=x;
  a->next=NULL;
  head->next=a;
  head=head->next;
  count++;
  }
  else if(x==-1&&count!=0){
   break;
  }
  else 
  {
   printf("输入中含有非法字符,请重新输入!\n");
   fflush(stdin);
   goto re_input;
  }
 }while(x!=-1);
  return p;
}

/****************************************/
Link* del(Link *p,int location)
{
    int i;
    Link *temp=p;
    Link *del=NULL;
    for(i=1;iif(temp->next==NULL)
        {
            printf("删除位置无效!\n");
            return p;
        }
        temp=temp->next;
    }
        del=temp->next;
        temp->next=temp->next->next;
        free(del);
        return p;
}
/****************************************/

void display(Link *p)
{
 Link* temp=p;
 while(temp->next!=NULL)
 {
  temp=temp->next;
  printf("%d ",temp->value);
 }
 printf("\n");
}

能帮忙看看该怎么改正吗

题主你好:

/*******************61*********************/
Link* del(Link *p,int location)
{
   if(temp->next==NULL)            //if判断放这里,不应该放在for循环里 表示对删除操作做合法性检查
        {                                          // if(temp->next==NULL)  如果链表是空的,则删除操作不合法,后面没必要执行了,直接返回
            printf("删除位置无效!\n");    
            return p;
        }
    int i;
    Link *temp=p;
    Link *del=NULL;
    for(i=1;i<location;i++)    {
        temp=temp->next;            //你说上面改成if (temp->next->next==NULL)就可以了只是巧合。因为如果你把原来的 if(temp->next==NULL) 放在这里
    }                                            //随着for循环的进行,temp在往后走,如果删除的是最后一个位置,会出现temp->next==NULL为真,就会出错返回
        del=temp->next;               //改成if (temp->next->next==NULL),删倒第二个结点也会为真。所以合法性检查应该放前面
        temp->next=temp->next->next;
        free(del);
        return p;
}
/******************78**********************/

有帮助请点一下采纳谢谢,可以参考我写的单链表的文章,有图解
https://blog.csdn.net/qq_41796226/article/details/125980808?spm=1001.2014.3001.5502

可以重点看看删除函数的情况(61-78),其他的应该是好的。
自己试了试,好像67行if的条件改成

if (temp->next->next==NULL)

就可以了。
但是我有点理解不了

修改处见注释说明,供参考:

#include<stdio.h>
#include<stdlib.h>
typedef struct link{
     int value;
     struct link *next;
}Link;
Link* init_list(void);//初始化
void display(Link *p);//链表输出
void del(Link *p,int location);//删除元素  //Link* del(Link *p,int location);//删除元素

int main()
{
    int cut;
    Link *q=init_list();
    printf("初始化链表为\n");
    display(q);
    printf("请输入要删除的数的位置:\n");
    scanf("%d",&cut);
    del(q,cut);
    display(q);

    return 0;
}

Link* init_list(void)
{

    //re_input:
    //;
    int x=0;
    int mask=0,count=0;
    Link* head=NULL;
    Link *p=(Link*)malloc(sizeof(Link*));
    head=p;
    printf("请输入数据(输入-1结束)\n");
    do{
       mask=scanf("%d",&x);
       if(x!=-1 && mask==1) //x!=-1&&mask!=0 mask值有可能是 -1,这里用 mask != 0 判断不准确
       {
           Link *a=(Link*)malloc(sizeof(Link*));
           a->value=x;
           a->next=NULL;
           head->next=a;
           head = a;//head=head->next;修改 这句这样写没毛病,但修改下更直观
           count++;
       }
       else if(x == - 1 && count!=0){
           break;
       }
       else
       {
           printf("输入中含有非法字符,请重新输入数据(输入-1结束)\n");//修改
           fflush(stdin);
           //goto re_input; 输入错误,并不需要重新生成头结点,从 do 这里开始即可,重新输入 x.
       }   //所以这 goto 语句不必要。
    }while(x!=-1);
    return p;
}
 
/****************************************/
void del(Link *p,int location) //Link* del(Link *p,int location) 删除函数不需返回头指针。
{
    int i;
    Link *temp=p;
    Link *del=NULL;
    for(i=1;temp->next && i < location;i++){ //for(i=1;i<location;i++) 修改
        //if(temp->next==NULL)        修改
        //{
        //    printf("删除位置无效!\n"); 修改
        //    return p;
        //}
        temp=temp->next;
    }
    if (location <= 0 || temp->next == NULL){//修改
       printf("删除位置无效!\n");
       return;
    }
    del=temp->next;
    temp->next=del->next; //temp->next=temp->next->next;这句这样写没毛病,修改更直观
    free(del);
    //return p; 修改
}
/****************************************/
 
void display(Link *p)
{
    Link* temp=p;
    while(temp->next!=NULL)
    {
       temp=temp->next;
       printf("%d ",temp->value);
    }
    printf("\n");
}