在没有malloc的情况下在C中实现一个简单的链表

在没有malloc的情况下在C中实现一个简单的链表,c,C,我在网上看到的所有实现都使用指针声明节点,然后使用malloc为它们创建空间,如下所示: struct Node { int data; struct Node *next; }; int main() { struct Node* head = NULL; struct Node* second = NULL; struct Node* third = NULL; head = (struct Node*)malloc(sizeof(struc

我在网上看到的所有实现都使用指针声明节点,然后使用malloc为它们创建空间,如下所示:

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

int main() 
{ 
  struct Node* head = NULL; 
  struct Node* second = NULL; 
  struct Node* third = NULL; 

  head = (struct Node*)malloc(sizeof(struct Node));  
  second = (struct Node*)malloc(sizeof(struct Node)); 
  third = (struct Node*)malloc(sizeof(struct Node));
...
struct node {
   int  id;
   struct node* next;
};

struct node head = {0, NULL};
struct node one = {1, NULL};
struct node two = {2, NULL};
struct node tail = {3, NULL};

int main(){
   head.next = &one;
   one.next = &two;
   two.next = &tail;
...
但我也可以在没有指针和malloc的情况下创建相同的对象,如下所示:

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

int main() 
{ 
  struct Node* head = NULL; 
  struct Node* second = NULL; 
  struct Node* third = NULL; 

  head = (struct Node*)malloc(sizeof(struct Node));  
  second = (struct Node*)malloc(sizeof(struct Node)); 
  third = (struct Node*)malloc(sizeof(struct Node));
...
struct node {
   int  id;
   struct node* next;
};

struct node head = {0, NULL};
struct node one = {1, NULL};
struct node two = {2, NULL};
struct node tail = {3, NULL};

int main(){
   head.next = &one;
   one.next = &two;
   two.next = &tail;
...
我的问题是,为什么第一个方法主要是使用的方法,为什么我们需要将每个节点声明为指针,为什么我们需要malloc?
只是想指出我知道为什么struct Node*next;在结构声明中声明为指针。

您应该使用局部变量而不是全局变量来执行此操作,但总体思路是相同的。您还应该使用数组,而不是成堆的不相关变量:

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

int main(){
  struct node nodes[4];

  for (int i = 0; i < 4; ++i) {
    nodes[i].id = (3 - i);

    if (i != 0) {
      nodes[i].next = &nodes[i-1];
    }
  }

  return 0;
}
那不行。您需要一个寿命更长的分配,这正是malloc提供的:

struct node* allocateNodes() {
  struct node *nodes = calloc(10, sizeof(struct node));

  return nodes; // Returns a pointer to an allocated structure, which is fine
}
问题是,如果你使用malloc,你就要负责调用free来释放内存,所以这就需要更多的工作


您将在代码中看到这两种样式的使用,具体取决于所讨论的变量的所需寿命。

如果您提前知道列表中将包含多少项,那么您最好使用数组而不是列表。链表的全部要点是能够在运行时增长到未知大小,这需要动态内存分配,即malloc。

我们通常不使用全局变量,也不主要编写所有代码,这就是为什么更多地使用第一个版本的原因,而且你很少知道链接列表创建时需要多长时间。如果你这样做了,那么可调整大小的结构就没有什么意义了。你不能在你的版本中添加任何额外的节点。如果您创建了一个、两个、三个节点,当您的程序运行时,用户会要求提供4个节点,您就有麻烦了。更改链接(例如对节点进行排序)的代码对于您的方法来说也是非常痛苦的。而且,已经证明,这样的链接列表通常是一个坏主意。在这里,即使您需要在中间删除,数组的性能也会更好。角落案例:您可以在程序启动时动态创建静态分配对象的列表。您可以将许多驱动程序名称和编译时未知的数字作为对象文件链接到可执行文件。每个驱动程序对象文件包含一个静态分配的静态结构驱动程序对象,并从_属性_构造函数中注册该对象。注册将为链表设置下一个指针。然后,main将在要迭代的驱动程序的程序启动列表中看到只生成一次运行时。对于main,该列表是静态的。链表还具有数组没有的其他有用属性,例如易于插入或删除项。