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:)我正在使用代码块