【问题标题】:How can a linked list node be defined "recursively"?如何“递归”定义链表节点?
【发布时间】:2019-02-06 12:54:44
【问题描述】:

我们今天刚刚被介绍给链表,我明白了这个概念,但声明让我很困扰,这是代码:

struct Node 
{ 
    int data; 
    struct Node *next; 
}; 

为什么这不是一个无限循环的声明?

编译器如何识别struct Node?内部的struct Node

对我的第二个问题视而不见后,我的看法如下:

  1. 创建一个结构,其中有一个整数和一个指向结构的指针 同类型。
  2. 在第一个结构体中创建指针指向的结构体,它包含一个整数和一个指向同类型结构体的指针。
  3. 创建由第二个结构中的指针指向的结构,该结构是由第一个结构中的指针指向的结构。
  4. ...

【问题讨论】:

  • 问题是结构内部没有Node 结构,您有一个指向Node 结构的指针 .
  • 所有指针,无论其类型如何,都具有相同的大小。
  • @AxeonThra 严格来说,这不一定是真的。它只是碰巧在“现代”PC 型系统上如此。但是,指针的大小始终是已知且固定的。
  • 在编译器读取struct Node *next 时,它(暂时)将其视为指向不完整类型的指针。
  • 大致意思是“它是一个指向某物的指针,虽然我还不知道something的大小,但指针的大小 i> 总是一样的”。

标签: c linked-list


【解决方案1】:
  1. 在第一个结构体中创建指针指向的结构体,它包含一个整数和一个指向同类型结构体的指针。

这就是你的推理错误的地方。创建指向某事物的指针不会自动创建它应该指向的事物。所以第一个对象是用一个指针创建的,并不意味着指针将指向有效的东西。就像我写的一样:

int *p;

它没有指向任何东西。 指针 的值是不确定的。我可以初始化指针:

int *p = NULL;

它仍然没有指向任何东西。但我可以给它一些地址:

int i = 1;
int *p = &i;

现在是指向某物。与节点中的指针相同。该节点只能保存某个节点的地址,但它不是必须的。这就是为什么链表不仅仅是一个节点的声明,也是一组函数(操作)的声明。这些函数旨在确保列表处于有效状态。每个节点都指向另一个节点,或者指向一个明确定义的终结符。

【讨论】:

  • 我明白了。但是通过“指针的值是不确定的”。你的意思是如果我不将它初始化为NULL,它可能会指向一个随机的内存块?
  • @Luyw - 差不多。这意味着(形式上)您对指针所持有的值一无所知(该值是地址)。使用任何具有不确定值的变量意味着程序的行为是不确定的。这就是为什么有人告诉人们初始化变量(并在第一次使用之前声明,其中一个有意义的初始值是可能的)被认为是好的做法。
  • @Luyw - 不。该类型用于静态类型检查。您必须不断转换为 char*。您可能会想,好吧,我将使用 void*。但是无论哪种方式,您都会失去编译器验证列表是否仅包含正确类型的结构的好处。这不是好的软件。
  • @Luyw - 指针类型不会被忽略。它是一个指向名为struct Node 的类型的指针。编译器只需要这么多信息就可以知道完整的对象布局(指针不是它们指向的东西)。
  • @Luyw - 所有结构指针都是相同的,这是有保证的。巧合的是,这足以制作有用的数据类型。其他指针可能会有所不同。但这超出了问题的范围。
【解决方案2】:

为什么这不是一个无限循环的声明?

好的首先指针指针,它指向intchardoublestruct没关系本质上是某事物开始的内存地址,其大小由体系结构决定。这就是为什么您可以在刚刚创建的struct 中声明指针。如果你运行这段代码:

struct node {
    int val;
    struct node next; // NOTE: I omitted * so it is not pointer it is struct
};

这会给你一个错误,因为struct node未知,它的大小也是未知的。所以相比:

struct node {
    int val;
    struct node *next;
};

指针类型是已知的,这里未知的是它指向什么。指针的大小也是已知的,因此您不会得到递归。

为了达到指针的目的。在 C 中:

int a = 5;
int *p = &a;
char *c = p;

是完全合法的,由程序员来跟踪这一点。所以底线struct node *next 是指向大概下一个节点(地址)的指针。这就是您没有出现recursion 的原因。

编译器如何识别结构节点内部的结构节点?

没有!!!这就是为什么我的第一个例子不起作用!!!!它识别指针类型。你基本上可以这样写:

struct node {
    int val;
    void *next;
};

对于您的机器,它将与以下内容相同:

struct node {
    int val;
    struct node *next;
};

希望对你有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-19
    • 2020-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多