C 链表节点消除函数

C 链表节点消除函数,c,struct,linked-list,singly-linked-list,function-definition,C,Struct,Linked List,Singly Linked List,Function Definition,我只是想消除包含偶数的节点x%2==0 我写了一个非常简单的函数,但是在我使用它之后,编译器不会显示修改过的列表,我也不知道为什么 如果头部包含一个偶数元素,它可以正常工作(我主要是这样做的),但当我试图从内部删除某些内容时,它实际上不想工作 我真的不知道我做错了什么 #include <stdio.h> #include <stdlib.h> struct test{ int val; struct test *next; }; void erase

我只是想消除包含偶数的节点
x%2==0

我写了一个非常简单的函数,但是在我使用它之后,编译器不会显示修改过的列表,我也不知道为什么

如果头部包含一个偶数元素,它可以正常工作(我主要是这样做的),但当我试图从内部删除某些内容时,它实际上不想工作

我真的不知道我做错了什么

#include <stdio.h>
#include <stdlib.h>
struct test{
    int val;
    struct test *next;
};

void erase (struct test *x)
{ 
    struct test *t;
    t=x->next;
    x->next=t->next;
    free(t);
    return ;
}

int main ()
{
    
    struct test *head,*p,*q, *aux;
    int n,i;
    
    printf("Number of elements:");
    scanf("%d",&n);
    p=(struct test * )malloc(sizeof(struct test));
    
    printf("First value:");
    scanf("%d",&p->val);
    p->next=NULL;
    head=p;
    for(i=2;i<=n;i++)
    {
        q=(struct test * )malloc(sizeof(struct test));
        printf("Value %d:",i);
        scanf("%d",&q->val);
        q->next=NULL;
        p->next=q;
        p=q;
    }
    
    for(p=head;p!=NULL;p=p->next) {
        printf("%d ",p->val);
    }
    while((head->val)%2==0) {
        aux=head;
        head=head->next;
        free(aux);
    }
    
    for( p=head ; p!=NULL; p = p->next) {
        if((p->next->val)%2==0) {
            erase (p);
        }
    }
    printf("\n");
    for(p=head ;p!=NULL;p=p->next) {
        printf("%d ",p->val);
    }
}


#包括
#包括
结构测试{
int-val;
结构测试*下一步;
};
无效擦除(结构测试*x)
{ 
结构测试*t;
t=x->next;
x->next=t->next;
自由(t);
返回;
}
int main()
{
结构测试*head、*p、*q、*aux;
int n,i;
printf(“元素数:”);
scanf(“%d”和“&n”);
p=(结构测试*)malloc(sizeof(结构测试));
printf(“第一个值:”);
scanf(“%d”,&p->val);
p->next=NULL;
水头=p;
对于(i=2;ival);
q->next=NULL;
p->next=q;
p=q;
}
for(p=head;p!=NULL;p=p->next){
printf(“%d”,p->val);
}
而((head->val)%2==0){
aux=头部;
头部=头部->下一步;
免费(aux);
}
for(p=head;p!=NULL;p=p->next){
如果((p->next->val)%2==0){
擦除(p);
}
}
printf(“\n”);
for(p=head;p!=NULL;p=p->next){
printf(“%d”,p->val);
}
}
在while循环之后

while((head->val)%2==0) {
    aux=head;
    head=head->next;
    free(aux);
}
指针头可以等于
NULL
。因此,下一个for循环可以调用未定义的行为。此外,在删除具有偶数值的节点后,将冗余地推进指针p

用这个代替循环

for( p=head ; p!=NULL; p = p->next) {
    if((p->next->val)%2==0) {
        erase (p);
    }
}
对于以下代码

if ( head != NULL ) {
    for( p=head ; p->next!=NULL; ) {
       if((p->next->val)%2==0) {
           erase (p);
       }
       else {
           p = p->next;
       } 
   }
}
while循环之后

while((head->val)%2==0) {
    aux=head;
    head=head->next;
    free(aux);
}
指针头可以等于
NULL
。因此,下一个for循环可以调用未定义的行为。此外,在删除具有偶数值的节点后,将冗余地推进指针p

用这个代替循环

for( p=head ; p!=NULL; p = p->next) {
    if((p->next->val)%2==0) {
        erase (p);
    }
}
对于以下代码

if ( head != NULL ) {
    for( p=head ; p->next!=NULL; ) {
       if((p->next->val)%2==0) {
           erase (p);
       }
       else {
           p = p->next;
       } 
   }
}
这里有一个bug:

for( p=head ; p!=NULL; p = p->next) {
    if((p->next->val)%2==0) {
        erase (p);
    }
}
列表中的最后一个元素发生了什么

p
不是
NULL

p->next
NULL

p->next->val
将取消对空指针的引用。

这里有一个错误:

for( p=head ; p!=NULL; p = p->next) {
    if((p->next->val)%2==0) {
        erase (p);
    }
}
列表中的最后一个元素发生了什么

p
不是
NULL

p->next
NULL


p->next->val
将取消对空指针的引用。

让我们看看函数的作用:

void erase (struct test *x)
{ 
    struct test *t;
    t=x->next;
    x->next=t->next;
    free(t);
    return ;
}
它获取指向某个结构的指针
x
,并假设它没有指向NULL

x -> [         ]
指向struct的那个指向另一个

x-> [          ] -> [         ]
该函数创建一个指针,指向该指针

x-> [          ] -> [NULL?  ]
t------------------>
t
现在可以指向NULL,但函数不检查它

然后它尝试重新指向
x
所指向的内容,指向未检查的对象所指向的任何内容,这可能会取消引用NULL

    [          ] -> [??NULL??  ] ??->?? ????[]????
t------------------>
x ----------------------------?-?-?-?-?-?-?-?-?->

此时,您将面临取消引用NULL的风险。

让我们看看函数的功能:

void erase (struct test *x)
{ 
    struct test *t;
    t=x->next;
    x->next=t->next;
    free(t);
    return ;
}
它获取指向某个结构的指针
x
,并假设它没有指向NULL

x -> [         ]
指向struct的那个指向另一个

x-> [          ] -> [         ]
该函数创建一个指针,指向该指针

x-> [          ] -> [NULL?  ]
t------------------>
t
现在可以指向NULL,但函数不检查它

然后它尝试重新指向
x
所指向的内容,指向未检查的对象所指向的任何内容,这可能会取消引用NULL

    [          ] -> [??NULL??  ] ??->?? ????[]????
t------------------>
x ----------------------------?-?-?-?-?-?-?-?-?->

此时,您有取消引用NULL的风险。

您可以显示您尝试的输入是什么吗,我刚刚复制并运行了代码,它似乎工作正常。是的,尝试放置77677如果它可以工作,它应该显示您7 7 6 7,然后显示7 7 6 7:)我正在使用代码块扫描您显示您尝试的输入是什么,我刚刚复制并运行了代码,它似乎工作正常。是的,尝试放置77677,如果它可以工作,它应该显示7 7 6 7,然后显示7 7 6 7:)我正在使用代码块