0

我正在用 C 实现一个链表。这是我制作的一个结构,它表示链表:

typedef struct llist {
  struct lnode* head; /* Head pointer either points to a node with data or NULL */
  struct lnode* tail; /* Tail pointer either points to a node with data or NULL */
  unsigned int size; /* Size of the linked list */
} list;

“llist”不是基本上没用吗。当客户使用这个库并创建一个新的链表时,他将有以下声明:

list myList;

所以在左大括号之前输入 llist 实际上是没有用的,对吧?下面的代码基本上做同样的工作:

typedef struct {
  struct lnode* head; /* Head pointer either points to a node with data or NULL */
  struct lnode* tail; /* Tail pointer either points to a node with data or NULL */
  unsigned int size; /* Size of the linked list */
} list;
4

4 回答 4

2

如果要在声明中引用它,则需要为结构命名。

typedef struct snode {
    struct snode* next;
    struct snode* prev;
    int id;
} node;

但是,如果您不引用其中的结构,则无需为其命名。


编辑

请注意,typedefis 和structare C 中的两个不同语句。

struct用于创建复杂类型:

struct snode {
    struct snode* next;
    struct snode* prev;
    int id;
};

读起来像是创建一个名为的结构,该结构snode存储对自身 ( nextand prev) 和 an int( id)的两个引用。

并且typedef用于制作类型别名

typedef struct snode node;

读起来像是为被调用的类型别名struct snodenode

于 2012-12-06T23:06:31.013 回答
1

在那种特殊情况下它是没有用的,但是,如果你想在结构本身有一个指向该结构的指针,那就需要它了。

这是因为结构在左大括号处是已知的,而 typedef 直到最后的分号才知道(简单,但在这里已经足够好了)。

所以你需要它来做类似的事情:

typedef struct sNode {  // structure can be used now
    int payload;
    struct sNode *next; // cannot use typedef yet
} tNode;                // typedef can be used now
于 2012-12-06T23:01:33.973 回答
1

是的,你是对的。除了 typedef 之外,显式命名结构只是一个习惯或约定问题。

请注意,无论哪种方式都几乎没有成本,因为llist它不是变量并且不占用内存。i这就像命名变量或- 编译形式之间的区别index一样,但一个可能比另一个更具可读性。

于 2012-12-06T22:59:11.933 回答
0

您可以扭转这一点:不是结构标签,而是整个 typedef 是多余的。

struct snode {
    struct snode* next;
    struct snode* prev;
    int id;
    };

现在您可以声明一个指针:

struct snode *ptr;

您甚至可以声明它们的数组:

struct snode mynodes[10];

您必须输入 struct 关键字,但这不会伤害编译器或人类读者(看看那个语法突出显示!)。

您甚至可以使用不完整的类型声明一个指向未知类型的指针(在编译时):

struct xnode *xptr=NULL;

当您想为某个库创建 API 时,这将派上用场,而调用者不知道该库的实际实现:

 struct gizmo *open_gizmo(char *path, int flags);
 int fiddle_with_gizmo(struct gizmo *ptr, int opcode, ...);

等等。typedef 将强制头文件将其所有内部内容“广播”给调用者,即使这不是必需的。

于 2012-12-06T23:35:25.917 回答