简体   繁体   English

为什么将链表的第一个节点声明为指针?

[英]Why the first node of a linked list is declared as a pointer?

Now I know that why pointers are used in defining linked lists. 现在,我知道了为什么在定义链接列表时使用了指针。 Simply because structure cannot have a recursive definition and if there would have been no pointers, the compiler won't be able to calculate the size of the node structure. 仅仅因为结构不能具有递归定义,并且如果没有指针,编译器将无法计算节点结构的大小。

struct list{
        int data;
        struct list* next;    // this is fine
};

But confusion creeps up when I declare the first node of the linked list as: 但是,当我将链接列表的第一个节点声明为:

struct list* head;

Why this has to be a pointer? 为什么这必须是一个指针? Can't it be simply declared as 不能简单地声明为

struct list head;

and the address of this used for further uses? 以及用于进一步使用的地址? Please clarify my doubt. 请澄清我的疑问。

There's no definitive answer to this question. 这个问题没有明确的答案。 You can do it either way. 您可以采用任何一种方式来做。 The answer to this question depends on how you want to organize your linked list and how you want to represent an empty list. 该问题的答案取决于您如何组织链接列表以及如何表示空白列表。

You have two choices: 您有两种选择:

  1. A list without a "dummy" head element. 没有“虚拟”头部元素的列表。 In this case the empty list is represented by null in head pointer 在这种情况下, 列表head指针中的null表示

     struct list* head = NULL; 

    So this is the answer to your question: we declare it as a pointer to be able to represent an empty list by setting head pointer to null. 因此,这就是您的问题的答案:我们将其声明为一个指针 ,以通过将head指针设置为null来表示一个列表。

  2. A list with a "dummy" head element. 带有“虚拟”头部元素的列表。 In this case the first element of the list is not used to store actual user data: it simply serves as a starting "dummy" element of the list. 在这种情况下,列表的第一个元素不用于存储实际的用户数据:它只是充当列表的起始“虚拟”元素。 It is declared as 声明为

     struct list head = { 0 }; 

    The above represents an empty list, since head.next is null and head object itself "does not count". 上面表示一个空列表,因为head.next为null并且head对象本身“不计数”。

    Ie you can declare it that way, if you so desire. 也就是说,如果您愿意, 可以这样声明。 Just keep in mind that head is not really a list element. 请记住, head并不是列表元素。 The actual elements begin after head . 实际元素head开始。

And, as always, keep in mind that when you use non-dynamically-allocated objects, the lifetime of those objects is governed by scoping rules. 而且,一如既往,请记住,当您使用非动态分配的对象时,这些对象的生存期由作用域规则控制。 If you want to override these rules and control the objects' lifetimes manually, then you have no other choice but to allocate them dynamically and, therefore, use pointers. 如果要覆盖这些规则并手动控制对象的生存期,则别无选择,只能动态分配它们,因此可以使用指针。

You can declare a list such a way 您可以这样声明列表

struct list head = {};

But there will be some difficulties in the realization of functions that access the list. 但是,实现访问列表的功能将存在一些困难。 They have to take into account that the first node is not used as other nodes of the list and data member of the first node data also is not used. 他们必须考虑到第一节点未用作列表的其他节点,并且第一节点data数据成员也未使用。

Usually the list is declared the following way 通常,列表通过以下方式声明

struct List
{
    // some other stuff as for example constructors and member functions
    struct node
    {
        int data;
        struct node* next;    // this is fine
    } head;
};

and

List list = {};

Or in C++ you could write simply 或者在C ++中,您可以编写简单

struct List
{
    // some other stuff as for example constructors and member functions
    struct node
    {
        int data;
        struct node* next;    // this is fine
    } head = nullptr;
};

List list;

Of course you could define the default constructor of the List yourself. 当然,您可以自己定义List的默认构造函数。

In this case for example to check whether the list is empty it is enough to define the following member function 例如,在这种情况下,要检查列表是否为空,就足以定义以下成员函数

struct List
{
    bool empty() const { return head == nullptr; }

    // some other stuff as for example constructors and member functions

    struct node
    {
        int data;
        struct node* next;    // this is fine
    } head;
};

In simple terms, if your head is the start node of the linked list, then it will only contain the address of the first node from where linked list will begin. 简而言之,如果您的头是链表的开始节点,那么它将仅包含链表从其开始的第一个节点的地址。 This is done to avoid confusion for a general programmer. 这样做是为了避免使普通程序员感到困惑。 Since the head will contain only address, hence, it is declared as a pointer. 由于头将仅包含地址,因此将其声明为指针。 But the way you want to declare is also fine, just code accordingly. 但是您要声明的方式也很好,只需进行相应的编码即可。 Tip: If you later on want to make some changes in your linked list, like deletion or insertion operations at the beginning of the linked list, you will face problems as you will require another pointer variable. 提示:如果以后要在链表中进行某些更改,例如在链表的开头进行删除或插入操作,则会遇到问题,因为需要另一个指针变量。 So its better to declare the first node as pointer. 因此最好将第一个节点声明为指针。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM