结构体和类型定义

9
在C语言中,以下内容是否等价?
// #1
struct myStruct {
    int id;
    char value;
};

typedef struct myStruct Foo;

// #2
typedef struct {
    int id;
    char value;
} Foo;

如果不行,我应该使用哪一个?什么时候用?
(是的,我看过 thisthis。)

1
https://dev59.com/3HNA5IYBdhLWcg3wH6AW - karlphillip
https://dev59.com/sXVC5IYBdhLWcg3wjx_u - karlphillip
3个回答

12

第二个选项不能引用自身。例如:

// Works:
struct LinkedListNode_ {
    void *value;
    struct LinkedListNode_ *next;
};

// Does not work:
typedef struct {
    void *value;
    LinkedListNode *next;
} LinkedListNode;

// Also Works:
typedef struct LinkedListNode_ {
    void *value;
    struct LinkedListNode_ *next;
} LinkedListNode;

9
不,它们并不完全等同。
在第一个版本中,Foo 是一个命名为 struct myStruct 的 typedef。
在第二个版本中,Foo 是一个未命名的 structtypedef
虽然在许多情况下两者都可以以相同的方式使用,但是有重要的区别。特别地,第二个版本不允许使用前向声明来声明 Foo 和它所代表的 struct,而第一个版本则允许。

抱歉,那是打错了。我想说的是 typedef struct myStruct Foo - Aillyn
谢谢,你能给出一个明显展示它们之间差异的例子吗? - Aillyn
@pessimopoppotamus:就像我说的那样,最明显的方法是在第一种情况下使用“typedef struct myStruct Foo;”来前向声明“struct”和“Foo”,并将其用作不完整类型(在适当的情况下),而这对于无名“struct”版本来说是不可能的。当然,在第一种情况下,您也可以使用“struct myStruct”作为类型的名称;在第二种情况下,没有类型的“完整”版本。 - CB Bailey

3
第一种形式允许你在类型定义完成之前引用结构体,因此你可以在结构体内部引用它本身或具有相互依赖的类型:
struct node {
  int value;  
  struct node *left;
  struct node *right;
};

typedef struct node Tree;

或者

struct A;
struct B;

struct A {
  struct B *b;
};

struct B {
  struct A *a;
};

typedef struct A AType;
typedef struct B Btype;

您可以像这样将两者结合起来:
typedef struct node {
  int value;
  struct node *left;
  struct node *right;
} Tree;

typedef struct A AType;  // You can create a typedef 
typedef struct B BType;  // for an incomplete type

struct A {
  BType *b;
};

struct B {
  AType *a;
};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接