typedef 结构在语法上是如何工作的?

How does the typedef struct work syntactically?

我是新手,所以如果我太笨了,我深表歉意。我无法理解如何使用 typedef。假设我有以下命令:

typedef struct {
    char pseudo[MAX_SIZE] ;
    int nb_mar ;
    } player ;

这会创建一个名为 player 的类型,它由一串字符和一个 int 组成,正确吗?

现在,如果我们有这行代码:

struct set_of_players {
    player T[NB_MAX_JOUEURS] ;
    int nb ;
    }; 

我不明白这是做什么的?我假设它创建了一个 struct set_of_players 类型的变量,但它叫什么?通常我看到这种命令,闭包amplesand后面有一个词代表变量名,但是这里什么都没有;我不明白。如果我没有为 set_of_players 完成 typedef struct,这还能工作吗?

终于有这行代码我看不懂了:

typedef struct set_of_players players;

老实说,我什至不知道这意味着什么。我假设这是我需要的 typedef 让前面的命令有意义,但我什至不知道它做了什么。

再次抱歉,如果我以错误的方式看待它,并且格式不佳。任何帮助将不胜感激,谢谢。

第一个语法

typedef struct {
    char pseudo[MAX_SIZE] ;
    int nb_mar ;
    } player ;

这定义了一个未命名的 struct。然后,使用 typedef,它为这个 struct 创建一个别名:player.

然后您可以这样声明您的 struct

player my_player;

类似于这个语法:

typedef struct s_player {
  char pseudo[MAX_SIZE];
  int nb_mar;
} player;

在第二种情况下,由于您的 struct 有名称,您可以这样声明 player

player my_player;
struct s_player my_player;

第二种语法

struct set_of_players {
  player T[NB_MAX_JOUEURS];
  int nb;
}; 

这定义了一个结构struct set_of_players.因为你没有typedef,你需要声明一个这种类型的变量,比如这个:

struct set_of_players my_set;

第三种语法

typedef struct set_of_players players;

这定义了类型 players,它是类型 struct set_of_players 的别名。

因为这会创建一个 struct set_of_players 的别名,所以它符合第二种语法:

struct set_of_players {
  player T[NB_MAX_JOUEURS];
  int nb;
};

typedef 语句允许您为给定类型创建别名。然后您可以使用别名或原始类型名称来声明该类型的变量。

typedef int number;

这为 int 创建了一个名为 number 的别名。所以下面两条语句声明了相同类型的变量:

int num1;
number num2;

现在使用您的示例:

typedef struct {
    char pseudo[MAX_SIZE] ;
    int nb_mar ;
} player ;

这将创建一个匿名结构并为其指定别名 player。因为结构没有名称,所以只能使用别名来创建该类型的变量。

struct set_of_players {
    player T[NB_MAX_JOUEURS] ;
    int nb ;
}; 

这会创建一个名为 struct set_of_players 的结构,但不会声明 typedef 也不会声明该类型的变量。另请注意,其中一个字段是我们之前定义的 player 类型的数组。您可以稍后声明此类型的变量,如下所示:

struct set_of_players my_set_var;

这一行:

typedef struct set_of_players players;

struct set_of_players 创建一个名为 players 的别名。在这种情况下,结构不是与 typedef 同时定义的,而是在别处定义的。所以现在你可以像这样声明一个这种类型的变量:

players my_set_var;

这与使用完整结构名称的版本相同。

你声明了这行代码后我才回复你typedef struct set_of_players players;

因此您的代码将像这样工作:-

假设:-

 #define MAX_SIZE 20
 #define NB_MAX_JOUEURS 2

现在您可以在我们的代码中使用如下所示的类型名称:-

 typedef struct set_of_players players;
 players PLAYERS;
 strcpy(PLAYERS.T[0].pseudo, "something");
 PLAYERS.T[0].nb_mar = 1;

 struct set_of_players {
      player T[NB_MAX_JOUEURS] ;// reffering to the above example you have created a array of struct `player` and its size is 2
   int nb ;
  };

你也可以像下面这样使用上面的结构:-

 struct set_of_players setplayers;
 strcpy(setplayers.T[0].pseudo, "something");
 setplayers.T[0].nb_mar = 1;

当您为其声明类型名称时,您不需要使用 struct set_of_players 创建变量,而是使用类型名称。这意味着你已经为你的结构指定了一个特定的名称,在你的例子中,它分别是 player 和 players。

typedef是一件很简单的事情。尽管它的名称如此,但它并没有定义新类型,而是为现有类型定义了别名(名称)。它在所有情况下的语法都是:

typedef <existing-type> <type-alias>

在 C 中,结构类型是这样定义的:

struct <tag> { <member-list> } ;

它的 类型 struct <tag>,这可能是您想要键入的更多内容,并且可能会被视为混乱。所以创建别名是一种常见的习惯用法,这样你就不需要在标签前到处加上 struct 。因此:

typedef struct <tag> { <member-list> } <type-alias> ;

typedef struct <tag> <type-alias> ;

两者都为 struct <tag> 创建别名,但第一个别名和结构都在同一语句中定义,第二个使用现有的结构定义。

给定这样的 typedef,而不是这样声明结构变量...

struct <tag> structure_variable ;

...您可以使用:

<type-alias> structure_variable ;

这只是语法糖 - typedef 不会影响代码行为或代码生成。

请注意,可以使用 匿名结构 (没有标签名称的结构)来定义 typedef,因此只能使用别名来实例化该结构:

typedef struct { <member-list> } <type-alias> ;

事实上,如果结构是自引用,你只需要一个标签名称 - 即它包含指向其自身类型的结构的指针(例如在链表中) ), 那么:

typedef struct <tag>
{
    struct <tag>* self ;  // Cannot use <type-alias> here;
                          // it does not exist yet.
    ...
} <type-alias> ;

typedefstruct 是两种不同的声明。 struct 定义结构类型。 typedef 为现有类型定义别名(它不会创建新类型)。它们可以组合成一个声明。两者都不会创建指定类型的对象(变量)。

struct player {
    char pseudo[MAX_SIZE];
    int nb_mar;
};

这是一个结构定义。它创建了一个名称为 struct player.

的新类型
typedef struct {
    char pseudo[MAX_SIZE];
    int nb_mar;
} player;

结构定义中的标记是可选的。如果省略它,结构类型是匿名的。这里我们将匿名结构定义与 typedef 组合在一起,使 player 成为匿名结构类型的别名。

typedef struct player {
    char pseudo[MAX_SIZE];
    int nb_mar;
} player;

这里我们创建一个名为 struct player 的结构类型和该类型的别名 player。 (结构定义的语法将标记紧跟在 struct 关键字之后;typedef 的语法将名称放在末尾。)

我们现在可以将类型称为 struct playerplayer

这是做同样事情的另一种方法:

struct player {
    char pseudo[MAX_SIZE];
    int nb_mar;
};
typedef struct player player;

通过两个单独的声明,我们创建了一个名为 struct player 的新类型,然后我们使用 typedef 为该类型定义了一个新名称,player

在所有这些示例中,我对结构标记和 typedef 名称使用了相同的标识符。没有要求它们必须相同,并且有一些编码约定,您可以在其中使用 struct player_stypedef ... player_t。但由于两个名称指的是同一类型,因此没有真正的理由使用不同的名称。它们至少应该以简单明了的方式相互关联。

请注意,结构类型的 typedef 从来都不是真正必要的。您可以只定义结构类型而不使用 typedef,并始终将类型称为 struct player。 typedef 所做的只是为已经拥有完美名称的类型定义一个新名称。 (优点是新名称是单一标识符;我个人认为这不是什么优点。)

另一点是,如果结构包含指向其自身类型的指针,则需要结构标记:

typedef struct node {
    int data;
    struct node *next;
} node;

您必须在 next 的声明中使用 struct node,因为 typedef 名称尚不可见。 (有一些方法可以使用前向声明来解决这个问题,但我不会深入讨论。)