【问题标题】:Function to remove entry from linked list in c从c中的链表中删除条目的函数
【发布时间】:2016-11-02 19:44:35
【问题描述】:

我在 Kochan 的 Programming in C 书的第 10 章中的练习 4 中挣扎。

任务如下:

编写一个名为removeEntry() 的函数来删除一个条目 链表。该过程的唯一参数应该是指向 名单。让函数在指向的条目之后删除条目 论据。

由于某种原因,该功能不起作用。如果我在其中执行printf(),它似乎可以工作,但它在main() 中不起作用。我认为鉴于我传递了一个指针,它会改变原来的(而不是按值传递)。但很明显,我做得不对。谁能帮我看看我哪里出错了?

// Function to remove an entry from a linked list

#include <stdio.h>

struct entry
{
    int value;
    struct entry *next;
};

int main(void)
{
    struct entry n1, n2, n3; // Original list

    struct entry *listPointer = &n1; // List pointer set up for iterating list

    void removeEntry(struct entry *pList);

    //listHead.next = &n1;  set list head to point to original beginning of list

    n1.value = 100;
    n1.next = &n2;

    n2.value = 200;
    n2.next = &n3;

    n3.value = 300;
    n3.next = (struct entry *) 0; // marks end of list


    // Print out values before removing entry
    printf("Before removing entry:\n");

    while (listPointer != (struct entry *) 0)
    {
        printf("%i\n", listPointer->value);
        listPointer = listPointer->next;
    }

    // reset listPointer to point to n1
    listPointer = &n1;

    // run function (DOES NOT WORK)
    removeEntry(listPointer);

    // print out values after (supposedly) removing entry
    printf("\n\nAfter removing entry:\n");

    while (listPointer != (struct entry *) 0)
    {
        printf("%i\n", listPointer->value);
        listPointer = listPointer->next;
    }

    return 0;
}

/********************* REMOVE ENTRY ********************************/

void removeEntry(struct entry *pList)
{
    //  <-------&n2
    pList = pList->next;

}

【问题讨论】:

  • “我以为我传递了一个指针,它会改变原来的”。 C 没有通过引用传递。都是价值传递。在这种情况下,您将按值传递指针。对指针值本身的任何更改对调用者都没有影响。调用者只会看到指针指向的内容的更改。一个简化的经验法则:调用者将看到在 LHS 上具有地址/指针 deref 的分配。其他作业不会。
  • 你需要这个:void removeEntry(struct entry **pList) { *pList = (*pList)-&gt;next; } 并用removeEntry(&amp;listPointer);调用它
  • 如果要删除 following 项,请先检查 is 是否有以下项。记住它的指针。将那个节点的next指针复制到当前节点的next指针。然后free你记得的指针(下一个节点)。
  • 谢谢凯勒姆,太棒了!但是为什么我需要一个双指针呢?抱歉,我显然需要了解更多关于指针的知识(希望我会在本章之后学习!)
  • 如果你想改变一个int,你需要一个指向int的指针。如果要更改字符,则需要指向字符的指针。如果要更改指针,则需要指向指针的指针。我希望这种模式是显而易见的 :-) 是的,请务必查看教科书。

标签: c pointers linked-list


【解决方案1】:

你的代码存在三个误区:

首先,正如 kaylum 在他的评论中提到的,函数参数在 C 中是按值传递的。这意味着每当您将参数传递给函数时,都会在函数中使用参数的副本。当函数返回时,这个副本就丢失了。因此,您将无法按照您的意图更改 pListremoveEntry() 内的值。

第二个问题(以某种方式链接)是您的函数removeEntry() 应该在函数参数指向的条目之后删除条目。所以如果pList 指向一个条目,你应该删除pList->next 指向的那个条目。如果这样做,您将同时解决您的第一个问题...

第三个问题,你应该在删除之前检查你要删除的元素是否存在。最终,释放与您删除的元素相对应的内存,但在您的情况下,这并不适用,因为您没有动态分配条目。

【讨论】:

  • 谢谢,我意识到在重新阅读问题后它并不完全正确(毕竟它确实要求将指向列表的指针作为参数,而不是指向指针的指针)。我很高兴有一些有用的东西,我错过了我删除了错误的项目的事实! (从好的方面来说,我现在知道你可以拥有指向指针的指针......:-) 我现在又回到了努力弄清楚如何访问我想要删除的条目(因为我只有一个参数,我没有不知道如何让 n2.next 进入 pList->next)。 hrmpf....
  • 如果你有一个指向一个条目的指针,那么你就可以访问它的成员。当一个成员指向它的下一个元素时,您也可以访问下一个元素......等等。
【解决方案2】:

耶!感谢 kaylum 和 Heyji,我终于做到了!谢谢两位!

C 语言总是很有趣,一个问题看起来如此困难,当你弄清楚它时,你会想知道你怎么能在如此简单的事情上挣扎......

void removeEntry(struct entry *pList)
{
    struct entry *pTemp = pList->next;
    //  <-------&n3
    pList->next = pTemp->next;

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-09
    • 2019-01-18
    • 2020-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-14
    • 2013-06-27
    相关资源
    最近更新 更多