我被困住了,因为我不明白这段代码在做什么:
struct node
{
int info; /* This is the value or the data
in the node, as I understand */
struct node *next; /* This looks like a pointer. But
what is it doing in real life? */
} *last; /* What is this and why is it
outside the body? What is this
thing doing? */
我知道创建节点时,它有一个值,并指向其他节点 但我不懂语法。
这是编写上述代码的更好方法吗?
是否有更简单的方法来编写相同的结构以便更好地理解?
在我的讲座中,他们认为学生对他们所教的内容有所了解。
答案 0 :(得分:1)
好吧,我们可以向您解释,但我们无法了解。
您提供的代码段是变量last
的定义,是指向新定义的结构类型node
的指针。它可以用其他方式写成:
typedef struct _node_t {
int info;
node_t *next;
} node_t;
node_t *last;
通过这种方式,我们将typedef
定义为某个短名称的类型定义的别名 - 在这种特殊情况下,它将两个字段的结构别名为node_t
。无论您将某些内容定义为node_t
类型,都告诉编译器您的意思是'这应该是前面两个字段的结构' ,而node_t *last
意味着'变量last
应指向node_t
类型' 。
所以,回到语法:
struct foo {
int a;
float b;
void *c;
} bar, *baz;
表示'定义结构类型foo
,并使其包含三个字段 - 整数a
,浮点b
和无类型指针c
,然后使变量bar
成为此结构类型,并使变量baz
指向此结构类型' 。
现在指针。您看到的内容称为“递归定义”,例如:类型提到了它自己的定义。它们没问题,如果语言支持它们(C确实如此),但是可以通过指定下一个节点指针只是无类型来避免链表节点结构中的递归定义:
struct node_t {
int info;
void *next;
};
这样您就不再引用node_t
类型的node_t
类型,但这会在使用此类型时给您带来一些不便(您必须明确地将next
投射到node_t
类型,例如((*node_t)(last->next))->info
,而不只是last->next->info
)。
如果您认为需要其他参考,请考虑查看交互式在线教程,例如http://www.learn-c.org/(我没有附属)。
答案 1 :(得分:0)
这是编写链表节点的最简单方法,但为什么要将其命名为last
?将其命名为node
,这使其更容易理解,但这是如何运作的。
首次创建链接列表时,它仅包含根节点(链接列表中的第一个节点),当您添加节点时,将info
字段填入节点将保留的数据(注意info
可以是任何类型的数据,字符,字符串,int ...)然后将next
设置为NULL
,因为该节点是列表中的最后一个节点。
当您添加另一个节点时,您将next
的值更改为指向刚刚添加的节点,并在刚刚创建的节点中将next
的值设置为NULL
,因为现在是列表中的最后一个节点。
您可以重复此操作以添加您的内存允许的任意数量的节点。
this link可以帮助您更好地理解结构
答案 2 :(得分:0)
typedef struct marks {
int m;
struct marks *next;
} marks_t;
这样我们定义一个结构,以便形成一个链表。现在我们将最后一个变量定义为“结构指针”,它给出了列表中下一个元素的地址(即仅作为结构)!
最后一个元素不指向任何节点(这里标记结构),因此指针变量具有NULL值。
现在定义第一个元素:
marks_t *list;
if (list == NULL) {
list = (marks_t *) malloc(sizeof(marks_t));
}
list->m = 15;
list->next = NULL;
现在,如果我们想在此旁边添加一个元素(即第二个元素):
marks_t *next1;
next1 = (marks_t *) malloc(sizeof(marks_t));
next1->m = 27;
next1->next = NULL;
list->next = next1; // Storing address of next1 structure in list