C11:匿名结构的TypeDEF与成员的指针一起工作吗?

发布于 2025-01-21 12:59:14 字数 390 浏览 3 评论 0原文

这是我通常会为C中的链接列表定义一个节点:

typedef struct _Node {
    int value;
    struct _Node * next;
} Node;

通过进行一些测试,我发现我能够通过匿名结构来使该定义工作,例如:

typedef struct {
    int value;
    struct Node * next;
} Node;

有理由这样做吗?我觉得它应该不起作用,因为节点在struct定义中还不是一种类型。

我的假设是struct节点 *下一步是一个匿名结构本身,它仅具有指向节点的指针。但是,如果是这种情况,那么如果尚未解决Typedef,我如何在此处使用节点类型?

Here is how I would usually define a Node for a linked list in C:

typedef struct _Node {
    int value;
    struct _Node * next;
} Node;

With some testing, I have found that I am able to get this definition to work via an anonymous struct, like this:

typedef struct {
    int value;
    struct Node * next;
} Node;

Is there a reason why this works? I feel like it shouldn't work since Node isn't a type yet in the struct definition.

My hypothesis is that the struct Node * next is an anonymous struct itself that only has a pointer to a Node. But if this is the case then how am I able to use the Node type here if the typedef isn't resolved yet?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我偏爱纯白色 2025-01-28 12:59:14

这似乎只有起作用。 “标签”名称空间和“普通标识符”的名称空间在C中完全不同。(C ++的规则略有不同)

您的成员nonymous struct> struct> struct点的下一个点对于不完整的struct节点,该节点是由同一声明向前指定的。

您的typedef命名匿名struct与该类型struct node不同。因此,您的指针Next指向编译器所知道的类型,而不是struct

避免此类头痛的一个好策略是转发声明struct nodetypedef是相同的:

typedef struct Node Node;
               ^^^^ ^^^^
               tag  typedef name

然后

struct Node {
  ...
};

This only seems to work. The "tag" name space and the name space of "ordinary identifiers" are completely distinct in C. (C++ has slightly different rules)

Your member next of the anonymous struct points to an incomplete struct Node that is forward-declared by that same declaration.

Your typedef names an anonymous struct that is distinct from that type struct Node. So your pointer next points to a type for which the compiler knows nothing more than that it is a struct.

A good strategy to avoid such headaches is to forward declare struct Node and the typedef to be the same:

typedef struct Node Node;
               ^^^^ ^^^^
               tag  typedef name

and then

struct Node {
  ...
};
喜你已久 2025-01-28 12:59:14

该声明

typedef struct {
    int value;
    struct Node * next;
} Node;

介绍了两个结构规范。第一个是带有Typedef名称Node的未命名结构。第二个是命名结构struct node

这两个结构指定词不同。

因此,例如,当您尝试将类型节点 *的指针分配给类型struct> struct> struct node *的指针时,编译器将发出警告或错误。 Versa是因为有不兼容的指针类型。

考虑以下演示计划。

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

typedef struct {
    int value;
    struct Node * next;
} Node;

int main( void )
{
    Node *head = malloc( sizeof( Node ) );
    head->value = 1;
    head->next = NULL;

    Node *next = malloc( sizeof( Node ) );
    next->value = 2;
    next->next = NULL;

    head->next = next;
}

例如,对于语句

head->next = next;

,编译器GCC 11.2发出以下警告。

<source>:18:16: warning: assignment to 'struct Node *' from incompatible pointer type 'Node *' [-Wincompatible-pointer-types]
   18 |     head->next = next;
      |                ^
ASM generation compiler returned: 0
<source>: In function 'main':
<source>:18:16: warning: assignment to 'struct Node *' from incompatible pointer type 'Node *' [-Wincompatible-pointer-types]
   18 |     head->next = next;
      |               

此外,您将无法放置类型struct node *的指针类型。 struct节点的定义未知。

例如,如果您将上述演示程序附加使用语句

printf( "%d\n", head->next->value );

,那么此时编译器将发布以下错误消息,

<source>:21:31: error: invalid use of undefined type 'struct Node'
   21 |     printf( "%d\n", head->next->value );
      |                               ^~

而您可以写作

typedef struct Node Node;

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

This declaration

typedef struct {
    int value;
    struct Node * next;
} Node;

introduces two structure specifiers. The first one is the unnamed structure with the typedef name Node. The second one is the named structure struct Node.

These two structure specifiers are different.

So for example the compiler will issue a warning or an error when you will try to assign a pointer of the type Node * to a pointer of the type struct Node * or vice versa because there are used incompatible pointer types.

Consider the following demonstration program.

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

typedef struct {
    int value;
    struct Node * next;
} Node;

int main( void )
{
    Node *head = malloc( sizeof( Node ) );
    head->value = 1;
    head->next = NULL;

    Node *next = malloc( sizeof( Node ) );
    next->value = 2;
    next->next = NULL;

    head->next = next;
}

For the statement

head->next = next;

for example the compiler gcc 11.2 issues the following warnings

<source>:18:16: warning: assignment to 'struct Node *' from incompatible pointer type 'Node *' [-Wincompatible-pointer-types]
   18 |     head->next = next;
      |                ^
ASM generation compiler returned: 0
<source>: In function 'main':
<source>:18:16: warning: assignment to 'struct Node *' from incompatible pointer type 'Node *' [-Wincompatible-pointer-types]
   18 |     head->next = next;
      |               

Moreover you will be unable to dereference a pointer of the type struct Node * because the type struct Node is an incomplete type. The definition of struct Node is unknown.

For example if you will append the above demonstration program with statement

printf( "%d\n", head->next->value );

then the compiler at this time will issue the following error message

<source>:21:31: error: invalid use of undefined type 'struct Node'
   21 |     printf( "%d\n", head->next->value );
      |                               ^~

Instead you could write for example

typedef struct Node Node;

struct Node {
    int value;
    Node * next;
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文