这个C函数如何工作?

时间:2015-11-20 09:15:54

标签: c function linked-list nodes

我正在读'学习C艰难之路'。这里一个函数List *List_create()有一个返回类型List,我理解但是我不知道*List_create()真的有用吗?这是什么功能?

 struct ListNode; //I also don't know what this does

 typedef struct ListNode{
      struct ListNode * next;
      struct ListNode * prev;
      void *value;
 }ListNode;

 typedef struct List{
      int count;
      ListNode *first;
      ListNode *last;
 }List;

 List *List_create()
 {
    return calloc(1,sizeof(List));
 }

4 个答案:

答案 0 :(得分:0)

该函数在动态内存中创建一个类型为List的对象的实例,用零初始化该对象的所有成员并返回指向该对象的指针。

实际上,不需要在动态内存中创建列表。 你也可以写

List list = { 0 };

不同之处在于,在第一种情况下,您将需要删除不再需要的动态分配列表。

在第二种情况下,编译器会费心删除列表对象。

但是在这两种情况下,您必须自己删除列表中的节点。因此,您需要编写一个函数,为列表中已分配的节点释放所有已分配的内存。

答案 1 :(得分:0)

List_create为列表结构分配内存,用于双向链表并初始化该结构。 struct需要有第一个和最后一个的空指针,以及0的count。此函数滥用了大多数平台上空指针的值为0的事实。而calloc只是将它分配的内存设置为0。

答案 2 :(得分:0)

嗯,这段代码中至少有一个基本错误,这让我想知道这是否是一个很好的学习来源。

返回类型为List*,而不是List。这是一个指向List类型的指针,这意味着它将一直存在,直到你释放它(通过调用free)。 calloc分配这样的内存并将其设置为全零,这是初始化结构的常用方法。

代码中的错误在函数声明符中,List_create()在现代C中不合适,它应该是List_create(void)。也许它只是一个错字,或者作者可能更习惯于C ++,但它仍然是错误的。但是它仍然是一个错误。

*放在函数名旁边而不是List旁边的原因是当你声明指针变量时,*附加到名称而不是类型

E.g。 List *foo, bar;声明了两个变量。 foo是指向List的指针,而bar不是指针。如果它写成List* foo, bar;(意思相同但对阅读代码的人来说很困惑),这就不那么清楚了。

答案 3 :(得分:0)

在C中,有两种方法可以处理结构:

  1. ,其中没有指针。在这种情况下,将结构传递给函数,或者从函数返回一个函数,需要按字节逐个复制整个结构。这适用于小结构,但对大结构效率低。

  2. 通过引用,在其中使用malloccalloc来“动态”分配将保存结构数据的一块内存,然后通过指针。

  3. 您的List_create函数选择使用按引用模型。这可能是正确的选择,因为它确保列表的所有持有者始终可以看到对列表的更新。

    如果它选择了 by value 模型,那么您必须始终确保在List结构的本地副本中拥有最新的更新。即List_add必须传回修改后的列表,这样不方便且容易出错。

    示例:引用

    List *List_create()
    {
        return calloc(1,sizeof(List));
    }
    
    void List_add(List* list, void *value) {
        /* TODO: actual insert code */
    }
    
    void example_caller() {
        List *list = List_create();
        List_add(list, whatever);
    }
    

    示例:按值

    List List_create()
    {
        List result = {0};
        return result;
    }
    
    List List_add(List list, void *value) {
        /* TODO: actual insert code */
        return list;
    }
    
    void example_caller() {
        List list = List_create();
        list = List_add(list, whatever);
    }