我看到人们在C中声明这样的结构:
struct node {
int data;
struct node *next;
}*head;
为什么我们在大括号之后有*头?头程如何在以后的程序中使用?
另外,为什么在内部使用结构是有效的?我认为它应该在被使用之前先定义。
答案 0 :(得分:3)
为什么我们在大括号之后有*头?
代码:
struct node {
int data;
struct node *next;
}*head;
声明一个名为head
的变量,它是指向struct node
实例的指针。在单个语句中混合类型的定义和该类型的变量的定义并不是一个好的做法,你通常应该避免这样做。
相当于:
struct node {
int data;
struct node *next;
};
struct node *head;
为什么在内部使用结构是有效的?
在struct中,声明了struct node*
。这只是指向另一个节点结构实例的指针。这在C中实现数据结构时非常常用,例如链表。
答案 1 :(得分:1)
为什么我们在大括号之后有*头?头程如何在以后的程序中使用?
struct node *
的{{1}}类型的全局变量。另外,为什么在内部使用结构是有效的?我认为它应该在被使用之前先定义。
这是来自c标准草案1570,§6.7.2.1
- 结构或联合不应包含具有不完整或函数类型的成员(因此,结构不应包含其自身的实例,但可包含指向其自身实例的指针),但具有多个命名成员的结构的最后一个成员可能具有不完整的数组类型;这样的结构(以及可能递归地包含这种结构的成员的任何联合)不应该是结构的成员或数组的元素。
醇>
我突出了相关部分。所以这意味着它可以是一个指针,但不是一个自身的实例,一个qoute的含义的例子
head
将无效,因为未定义类型struct node {
int data;
struct node next;
} *head;
,但这样做
struct node
并且它等同于原始代码。
此功能使得精彩的链表成为可能,因为struct node *head;
struct node {
int data;
struct node *next;
};
是指向next
的指针,那么您可以将当前节点链接到同一类型的另一个节点,依此类推,它是通常这样做,以便最后一个节点链接到一个特殊值,struct node
,这将是一个非常简单的例子
NULL
更复杂的程序将具有列表中#include <stdlib.h>
#include <stdio.h>
#include <string.h>
struct node {
int data;
struct node *next;
};
int main(int argc, char **argv)
{
struct node *head;
struct node *next;
struct node *current;
head = malloc(sizeof(*head));
if (head != NULL)
{
head->data = 1;
head->next = NULL;
}
next = malloc(sizeof(*next));
if (next != NULL)
{
next->data = 2;
head->next = next;
next->next = NULL;
}
for (current = head ; current != NULL ; current = current->next)
fprintf(stderr, "node@%p: %d\n", current, current->data);
free(next);
free(head);
return 0;
}
/ create
/ append
个节点的功能。
答案 2 :(得分:0)
另外,为什么在自身内部使用结构体是有效的
答案 3 :(得分:0)
大括号后的*head
声明会创建指向struct node
的指针类型。您可以声明指向结构的指针,而无需编写struct node *
虽然这不是一个好习惯,但应该避免。
此外,这是可选的。