C链接列表/ - >操作者

时间:2013-07-27 11:39:22

标签: c linked-list

所以我一直在努力理解链接列表的概念(在看一些示例代码时,我在互联网上发现了这个。现在,如果我可以请某人确认我是否正确掌握了一些概念。我将绘制我认为每个代码链接的图表。

#include <stdio.h>
#include <stdlib.h>

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

int main (int argc, char *argv[]){

   struct ListItem a;  
   a.data = 0;
   a.next = NULL;
   struct ListItem b;
   b.data = 1;
   b.next = NULL;
   struct ListItem c;
   c.data = 2;
   c.next = NULL;

   a.next = &b;
   b.next = &c;

   int counter = 0;
   struct ListItem *i;
   for (i = &a; i != NULL; i = i->next){

      printf("Item %d value is %d\n\r", counter, i->data);
      counter++;
   }


   return 0;
}

代码段1:

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

这将创建一个名为ListItems的结构。该结构有两个组件,一个用于存储数据的组件和一个指向struct ListItem类型的另一个结构的指针。我想象链接列表如下:

enter image description here

这是一种可视化的正确方法吗?


代码段2:

struct ListItem a;  
a.data = 0;
a.next = NULL;
struct ListItem b;
b.data = 1;
b.next = NULL;
struct ListItem c;
c.data = 2;
c.next = NULL;

是的,我知道它可以缩短但我只是这样做,看看我是否能理解这个概念。现在,这个片段创建了一个struct ListItem类型的变量“a”,“b”和“c”。然后它将每个结构的第一个成员(数据)分别设置为0,1,2,将第二个成员(下一个)设置为NULL。所以我的可视化现在是这样的:

enter image description here

现在更多问题

问题1:当我们最初指向NULL时,它指向什么都没有?我们为什么要做这个?最初没有指向什么?


摘录3:

   a.next = &b;
   b.next = &c;

这个让我们在每个变量a,b(它是一个结构)中的下一个分别指向b和c的地址存储位置。

我的可视化:enter image description here

问题:它怎么能这样做?结构本身不是存储在多个内存地址上(4表示int等)


摘录4:

   int counter = 0;
   struct ListItem *i;
   for (i = &a; i != NULL; i = i->next){

      printf("Item %d value is %d\n\r", counter, i->data);
      counter++;
   }

这是我曾经有点困惑的片段。现在,我们预留了一个名为counter的整数,并将其初始化为零。此外,我们创建一个名为i的变量,它指向struct ListItem类型。现在有人可以向我解释for循环吗?我对它正在做的事情感到有点困惑。特别是,i = i->接下来,我对此并不熟悉。我知道它相当于i =(* i).next但不确定它到底是做什么的。有人可以创建一个快速图表吗?

另外:如果有人对某些有用的网站有任何好的资源/链接(没有双关语),以帮助我理解链接列表,可以随意发布它们。

3 个答案:

答案 0 :(得分:2)

Q1:未初始化的指针不指向“无”。如果你没有设置它的值,它可以(并且将)指向任何,包括(但不限于)nul值,越界内存或最后一个密码你进入了一个网站。

当你做

时,问counter的价值是什么并没有什么不同
int counter;
...
printf ("counter is %d\n", counter);

因此,将next指针设置为NULL有两个不同的目的。首先,您确定它是一个“已知”值,而不是任何随机值。其次,按照惯例,NULL值表示它不指向任何有效位置。

(这是'约定',因为NULL有效地存储数值'0'。这是一个内存地址 - 因为你在谈论指针 - - 完全有效。它的日常用途并不多。)

答案 1 :(得分:0)

对问题1的回答:不,最初结构是未初始化的,并且其next字段很可能指向没有正确的,但可能是它不包含NULL

问题2:每个结构变量的地址都在内存中。当然它的字段(组件)也有它们的地址。整个结构的地址是其第一个字段的地址。

对于代码段4中的i = i->nexti是指向当前列表项的指针(最初设置为a的地址)。赋值获取当前列表项的字段next的值,并将此值移动到i。所以i现在指向下一个列表项。这只会将i一个项目向右移动(它在列表上进行迭代)。当i指向列表的最后一项时,i->nextNULL,因此处理后最后一项i变为NULL并且循环终止。

答案 2 :(得分:0)

  

问题1:当我们最初是指向NULL的指针时,它指向的是什么?我们为什么要做这个?最初没有指向什么?

是。 NULL不能是任何节点的地址,因此它不指向任何东西。我们初始化为NULL以避免程序中的错误。它还假设使用某个默认值初始化变量的良好做法。

假设你没有用NULL初始化next,那么next将指向一些垃圾节点,如果你的代码有错误,那么访问未分配的内存是未定义的行为。而未初始化的下一个值是垃圾,不同的运行会表现出不同的方式。但是如果初始化为NULL,它将产生常量结果,因此很容易跟踪错误。阅读:Initialize a variable

  

问题2 :特别是i = i->next,我对此并不熟悉。我知道它相当于i = (*i) .next,但不确定它的真正作用。有人可以创建一个快速图表吗?

在表达式i = i->next;中,您将下一个节点的地址分配给i指针。内存中的链表可以假设为:

 a         b        c 
+---+    +---+    +---+                               
| a |--->| 1 |--->| 2 |---+
+---+    +---+    +---+   |                                
                         null  

最初在for循环中将表达式a中的节点i的地址分配给i = &a,它就像这样:

 a         b        c 
+---+    +---+    +---+                               
| a |--->| 1 |--->| 2 |---+
+---+    +---+    +---+   |                                
  ▲        ▲             null  
  i        i->next    


  i = i->next; 
  ^      ^
  |      next to `i` in linked list
   current node 

运营商->呼叫Member selection via pointer,请注意istruct ListItem*类型的指针。
您也可以使用名为.的{​​{1}}运算符执行相同操作,如下所示:

Member selection via object name

运算符 i = (*i).next; ->都可用于访问对象的成员。运算符.对地址有用,->对值变量很有用。

  

问题3 :我们预留了一个名为counter的整数并将其初始化为零。此外,我们创建一个名为i的变量,指向struct .类型。现在有人可以向我解释for循环吗?

在您的代码中,ListItem用于我上面解释的,以便在通过链表时保持当前节点的地址,而i仅用于计算链表中的节点。

counter
  

另外:如果有人对某些有用的网站有任何良好的资源/链接(没有双关语),以帮助我更好地了解链接列表,请随时发布。

从源代码中读取,其中概念用图表和代码解释。您可以参考:How to create Linked list using C?