C、 列表的最后一个元素不指向任何内容

C、 列表的最后一个元素不指向任何内容,c,list,pointers,recursion,linked-list,C,List,Pointers,Recursion,Linked List,我有一个问题:下面的函数将指针列表复制到第二个链接列表中,如果它们相等。 外汇 列表1=12356777 呼叫后的结果将是: 列表2=37 node *seqdup(node *lis) { if(lis == NULL) return NULL; else if (lis->next != NULL) { if(lis->data == lis->next->data)

我有一个问题:下面的函数将指针列表复制到第二个链接列表中,如果它们相等。 外汇 列表1=12356777

呼叫后的结果将是:

列表2=37

node *seqdup(node *lis)
{
    if(lis == NULL)
        return NULL;
    else if (lis->next != NULL)
        {
            if(lis->data == lis->next->data)
                {
                    node *p;
                    p = newnode();
                    p->data = lis->next->data;
                    p->next = seqdup(lis->next);
                    return p;
                }
            else
                return seqdup(lis->next);
        }
}
我知道这是一个无用的函数,是为了学校考试

问题是: 我做了一个学校作业,因为没有包括“if(lis->next==NULL)return NULL;”这样的条件,我在练习的10分中得到了2分 由于读取列表的最后一个节点时,如果lis为1 3 4,函数将不执行任何操作:fx

对于第一个节点,lis->next!=NULL他发现1==1`所以在lis 2中复制 第二步,lis->next!=空,和1!=3,所以记录电话,但没有副本 但是第三次,从3开始!=它什么也不做

问题是,只要我在递归调用后分配lis->next,第二个列表的最后一个复制节点基本上会指向一个什么都不做的函数

显然,我的老师对这个问题很严厉,因为有很多简单的方法可以解决它。然而,我的问题是:为什么它仍然有效


试着把它写下来并编译,然后像一个符咒一样工作:/

如果它对你有用,那就意味着你很幸运,当条件失效时,eax寄存器恰好为零。因此,就好像在函数末尾有一个
返回NULL


当我在我的编译器中测试时,情况并非如此,代码也不起作用。对我来说,eax寄存器保存着lis的值,因此就好像在函数的末尾有
返回lis
。这就产生了一个永远循环的列表。

澄清一下:你是在问“当我的函数通过一个没有显式返回的代码路径时,它怎么会返回
NULL
?”类似这样的问题是的。在运行该函数之后,我用一个print函数(只要lis!=NULL,就可以打印数据字段)检查返回的列表,结果一切正常。我明白了:实际上这就是为什么我认为,这基本上是运气的问题。但同时,这也很奇怪,因为我尝试运行该函数150.000次(用另一个函数调用它),但没有遇到任何问题。顺便说一句:我是在说一些愚蠢的话吗?原谅我,我对编程基本上是新手(今年开始上大学,来自一个编码不是一门学科的学校)。然而,我知道这个问题是C语言的典型问题,声明一个变量不会将它设置为未知(或者至少他们是这样解释的)。就像声明int a一样;并且打印它。@Eloh666它是否工作的问题主要取决于编译时,而不是运行时。如果编译器生成的汇编代码在函数中的该点将eax寄存器设置为零,那么它将始终正常工作。如果它生成的代码将eax寄存器设置为其他值,那么它几乎总是会失败。多次运行它不太可能改变任何事情。使用不同的编译器,或者稍微修改代码,会产生不同的结果。我知道,我并没有真正想到这一点,但它确实非常有意义。谢谢这是一个很好的例子,说明了为什么你永远不应该依赖于未定义的行为。这会让你得出错误的结论。我知道,真的。问题是,知道它不应该工作,它仍然在工作,这让我感到疑惑。然而,起初我确实认为这是对编译器的优化,然而注册表选择的解释非常有意义。