【问题标题】:C Linked list only contains first element...not sure what happens to restC链表只包含第一个元素......不知道会发生什么
【发布时间】:2011-01-08 11:45:59
【问题描述】:

几天前我发布了一个关于 C 中的链接列表的问题。我认为一切正常,然后教授给我们发电子邮件说,而不是这个签名:

int insert_intlist( INTLIST* lst, int n); /* Inserts an int (n) into an intlist from the beginning*/

他无意中的意思:

int insert_intlist( INTLIST** lst, int n); /* Inserts an int (n) into an intlist from the beginning*/

我想我现在很酷,因为我有一个指向指针的指针,我可以将指针移到 main 之外,当我返回 main 时,我仍然拥有完整的链表。

他开始给我们这个:

INTLIST* init_intlist( int n ) 
 {
    INTLIST *lst; //pointer to store node
    lst = (INTLIST *)malloc(sizeof(INTLIST)); //create enough memory for the node
    lst->datum = n; //set the value
    lst->next = NULL; //set the pointer
    return lst; //return the new list
}

这只是在 main 中像这样初始化列表:

   if (lst==NULL)
                  lst = init_intlist(i);
               else
                  insert_intlist(lst, i); 

lst 是 INTLIST* 类型,因此它定义为 INTLIST* lst。所以我从像 1 3 4 9 这样的文本文件中读取了一些数字。 它应该由此创建一个链表......所以第一个数字将转到 init_intlist(1);这是上面定义的。然后它在这种情况下抓取下一个数字 3 并调用 insert_intlist(lst, 3)。好吧,这是我的 insert_intlist,我要做的就是在列表的开头插入:

int insert_intlist(INTLIST** lst, int n )
 {
    INTLIST* lstTemp; //pointer to store temporary node to be added to linked list
    lstTemp = (INTLIST *)malloc(sizeof(INTLIST)); //create enough memory for the node
    lstTemp->datum = n; //assign the value

    //check if there is anything in the list,
    //there should be, but just in case
    if(*lst == NULL)
       {
          *lst=lstTemp;
          lstTemp->next=NULL;
       }
    else
       { 
          lstTemp->next = *lst; //attach new node to the front
          *lst = lstTemp; //incoming new node becomes the head of the list
       } 

    return 0; 
 }

因此,如果列表最初包含 1,则此函数将简单地创建一个新节点,然后使此临时节点->next 指向列表的头部(我认为是 lst),然后将列表的头部重新分配给这个新的临时节点。

看起来一切正常,但是当我尝试将列表打印到屏幕上时,它只打印数字 1。

有人知道我做错了什么吗?

【问题讨论】:

  • 不是很有帮助,但你有没有考虑过勒死你的教授? :)
  • 我认为你应该给你的教授一个不及格的分数!
  • 我同意他刚刚向全班同学发送了电子邮件,让他们知道他的 .h 文件对于各种功能都不正确……天哪,这真是一团糟。看起来教授甚至没有编码这个。也许他是从那个疯狂的教授那里得到这个任务的

标签: c linked-list


【解决方案1】:

你被传递了一个指向指针的指针。您想更改指向的指针,而不是指向指针本身的指针。这有意义吗?

if(lst == NULL)

在这里,您正在检查是否传递了一个 NULL 指针。错误检查的良好做法,但不适用于您在那里所做的事情。如果lst 为NULL,那么你甚至没有指向指针的指针,不能做任何事情,并且应该返回一个非零错误代码而不做任何其他事情。

一旦你确定你的指针不为 NULL,然后你看看它指向的指针 (*lst)。指向的指针是指向第一个列表项的指针。如果那个指针是NULL,那么你把它改成新项目的指针。基本上,在你使用lst 的地方,你应该使用*lst(*lst)。 (记住:* 运算符在-> 运算符之后运行!因此,要在lst [pant, pant] 指向的指针指向的对象中获取一个字段,你使用(*lst)->whatever。)

附:这种指针工作对于学习成为一名优秀的程序员至关重要,尤其是 C 语言。

附言你弄错的另一件事是,而不是

insert_intlist(lst, i);

你应该这样称呼它

insert_intlist(&lst, i);

...对于布朗尼点数,请检查返回码是否有错误。

【讨论】:

  • 谁能给我解释一下为什么&lst我知道&是...的地址...但是说真的这门课真的很难,这是我们的第一个作业,我必须在我的基础上学习C拥有。
  • &lst 因为您传递的是指向列表指针的指针,而 lst 只是指向列表的指针。请注意,“pointer to”与“address of”同义。
  • 谁能推荐一本好书,这东西真的很难,我不敢相信我能走到这一步......
  • C 编程语言?虽然我不知道它在数据结构上的东西有多好,如果有的话。您还可以在 Google 上搜索“C 数据结构”或“C 链表”,看看会出现什么。作为记录,这是数据结构类需要开始的地方。在继续使用双链表、二叉树、队列、稀疏数组和其他结构之前,您必须先了解这种单链表。
  • P.S. C 编程语言 由编写该语言的人 Kernighan 和 Ritchie 编写;国际标准书号 978-0131103627。
【解决方案2】:

我想到的第一个问题是insert_intlist() 你正在做lst = lstTemp;。这应该是*lst = lstTemp;。这样,您将分配给提供给您的列表指针,而不是分配给列表指针指针(它不会更新函数之外的任何内容)。

【讨论】:

    【解决方案3】:

    由于您在插入函数中使用指向另一个指针的指针,您可以更改后者实际指向的内存位置。我稍微更改了插入代码,它工作正常:

    int insert_intlist(INTLIST** lst, int n )
    {
        INTLIST* lstTemp; //pointer to store temporary node to be added to linked list
        lstTemp = (INTLIST *)malloc(sizeof(INTLIST)); //create enough memory for the node
        lstTemp->datum = n; //assign the value
    
        //check if there is anything in the list,
        //there should be, but just in case
        if(*lst == NULL)
        {
          lstTemp->next=NULL;
          *lst = lstTemp;
        }
        else
        { 
          lstTemp->next = *lst; //attach new node to the front
          *lst = lstTemp; //incoming new node becomes the head of the list
        } 
    
    return 0; 
    

    }

    编辑:我看到你编辑了你的问题。在这种情况下,也许你在 main() 中以错误的方式调用了插入函数。试试这个

    int main()
    {
        INTLIST *head;
        head = init_intlist(42);
        insert_intlist(&head, 41);
        display(head);
        return 0;
    }
    

    【讨论】:

    • 我有同样的东西,但是当我尝试打印列表时它只显示一个元素。
    • 你是如何打印列表的?
    • 如果有帮助,我在这里发布了整个代码:dpaste.de/ZDKt 我可以验证它是否适合我。可能是你用来遍历链表的函数有问题?
    • 好吧,我叫错了...你能解释一下为什么是 &lst 而不是 lst???
    • jimh86,请参阅我发布的第一行。 lst 是一个指向 INTLIST 类型的指针。插入函数需要一个双指针。指针是一个变量,就像任何其他变量一样。所以你用 & 运算符传递 lst 指针的地址。
    【解决方案4】:

    在 lstTemp->next=lst 之后检查 lstTemp->next == NULL;

    【讨论】:

      猜你喜欢
      • 2019-09-04
      • 2020-08-23
      • 1970-01-01
      • 1970-01-01
      • 2012-07-21
      • 1970-01-01
      • 2018-09-30
      • 2011-09-05
      相关资源
      最近更新 更多