c - 链表未被修改

标签 c linked-list

我正在尝试将一个节点添加到链接列表的开头,但该列表并未在我的一个函数中被修改,而是在另一个函数中被修改...

这是我要在开头插入的函数。

llist* insert_beginning(llist *list, gymnast_info *g) {                         
     llist *new = (llist *)malloc(sizeof(llist));                                
     new->g = g;                                                                 
     new->next = list;                                                           
     list = new;                                                                 
     return list;                                                                
 } 

在此函数中,链表被正确修改

llist *add_sorted_name(gymnast_info *ginfo, llist *head) {
    llist *accu = head;
    while (accu) {
        // Beginning of list                                                         
        if (strcasecmp(accu->g->lastname, ginfo->lastname) > 0
                && accu == head) {
            return insert_beginning(head, ginfo);
        }
......
    }
}

但是,在这一次中,情况并非如此。它返回正确的列表,但不会修改输入的列表。我不知道为什么。

llist *add_sorted_country(gymnast_info *ginfo, llist *head) {
    llist *accu = head;
    int country = ginfo->country;
    while (accu) {
        //Beginning of the list                                                      
        if (accu->g->country >= country && accu == head) {
            return insert_beginning(head, ginfo);
        }
        .......
    }
}

最佳答案

当前insert_beginning仅更改a的指向地址 指针的本地副本。调用者看不到更改。但是因为 您返回新的头,调用者必须检查返回值并替换 列表的头部。

add_sorted_nameadd_sorted_country 就是这样做的,因为它们 马上归还新头。我们看不到的是调用者如何 add_sorted_nameadd_sorted_country 正在处理结果。如果 他们这样做:

add_sorted_country(ginfo, head);
do_something_with(head);

那么你就不会看到头部有任何变化,因为你忽略了它。你会 需要像这样调用它们(类似于 realloc 调用):

llist *tmp = add_sorted_country(ginfo, head);
if(tmp == NULL)
{
    // error handling
    // do not continue
}

head = tmp; // assigning possible new head

这样的 API 很好,但是您必须确保始终检查 函数的返回值。这可能是首先的问题。

执行此操作的另一种方法(也许更安全)是将指针传递给指向头部的指针,并让 改变头部的函数,通过双指针改变。

int insert_beginning(llist **list, gymnast_info *g) {
    if(list == NULL)
        return 0;

    llist *new = calloc(1, sizeof *new);                                
    new->g = g;                                                                 
    new->next = *list;
    *list = new; // setting 'new' as new head
    return 1;                                                                
}

然后add_sorted_name应该看起来像这样

int add_sorted_name(gymnast_info *ginfo, llist **head) {
   if(head == NULL)
       return 0;

   llist *accu = *head;
   while (accu) {
       // Beginning of list                                                         
       if (strcasecmp(accu->g->lastname, ginfo->lastname) > 0
       && accu == head) {

           return insert_beginning(head, ginfo);
       }
   ......
   }
}

关于c - 链表未被修改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48615828/

相关文章:

c - 从二维数组打印字符时出现颠倒的问号

C 在字符串中搜索单词

c - 如何访问 C 中的 union

c++ - 从给定的链表在 C++ 中创建反向链表

java - 双链表的冒泡排序

C 用对应于索引的值初始化一个(非常)大的整数数组

c - C中静态函数和非静态函数的区别

java - 栈式linkedList中的push函数是如何工作的?

c++ - 对链表打印函数的 undefined reference

c++ - 链接 ArrayList 实现