按特定标准删除链表的元素

我写过这个函数:

List* delPaintingCode(List* head, char *code) { List *p,*q; for(p=head;p!=NULL;q=p,p=p->next) { if(!strcmp(code,p->code)) { if (p==head) { q=head; head=p->next; free(q); } else { q->next=p->next; free(p); p=q; } } } return head; } 

当我在另一个函数中调用它时:

 void delpainting() { char code[50]; printf("code "); scanf("%s",code); List *head=NULL; head=delPaintingCode(filetolist,code); } 

程序崩溃了。 我有一个警告: passing argument 1 of delPaintingCode from incompatible pointer type

那么我应该如何将字符串传递给函数呢?

导致崩溃的逻辑问题在于代码的if (p==head)分支:当你删除初始元素时,你释放head而不更新p 。 这导致在下一次迭代时取消引用释放的指针。

你可以通过引入一个带有head的假节点来解决问题,然后返回next ,如下所示:

 List fake; fake.next = head; // This loop always looks ahead by one element, ie at p->next. for(List *p = &fake ; p->next != NULL ; p = p->next) { if(strcmp(code, p->next->code)) { continue; } List *q = p->next; p->next = q->next; free(q); } return fake.next; 

这种方法也适用于初始元素,因为我们在列表中添加了一个假头,因此第一次围绕p->next与head相同。 这让我们统一了头元素和所有其他元素的处理。