0

I referred to the tutorial below and later realized it is wrong way of declaring struct using typedef.

 typedef struct

 {
  char name[namesize];
  char address[addresssize];
  int YearOfBirth;
  int MonthOfBirth;
  int DayOfBirth;
} PersonalData;

then declare:

PersonalData x;

However, I believe the right way is

 typedef struct personaldataStruct
 {
  char name[namesize];
  char address[addresssize];
  int YearOfBirth;
  int MonthOfBirth;
  int DayOfBirth;
  } PersonalData;

then declare:

  PersonalData x;

Did the author mislead me? or both ways are correct? please confirm. Here is the tutorial http://www.iu.hio.no/~mark/CTutorial/CTutorial.html

4

2 回答 2

3

这两种方法都没有任何形式上的“不正确”。

前者声明了一个无标记的结构类型和该结构类型的 typedef 名称PersonalData。后者声明了一个结构类型struct personaldataStruct和该结构类型的同义 typedef 名称PersonalData。声明的personaldataStruct部分通常称为“结构标记”。

只要您使用PersonalDatatypedef name 来引用该结构类型,如

PersonalData x;

您不会看到这两个声明之间有任何区别。在这两种情况下x,都将声明相同。

后一种方法为您提供了另一种引用相同结构类型的方法struct personaldataStruct- 如果出于某种原因您希望这样做。例如,当使用后一种声明时,您也可以将您的声明x

struct personaldataStruct x;

这完全等同于PersonalData x;声明。

就个人而言,我更喜欢使用带有 struct 标签的方法,因为它为我提供了引用类型的替代方式,这在某些情况下可能会派上用场(例如,当结构类型必须引用自身时)。但在大多数非自我参照的情况下,前一种方法会完全没问题。

于 2013-10-10T03:51:16.800 回答
0

两者都是正确的。第一种形式(没有标签)的唯一真正问题是,因为 typedef 名称直到定义结束才可见,因此无法从其自己的定义中引用结构。这是一个常见的要求;例如,链表、树或其他类似图形的数据结构中的节点通常需要指向相同类型的其他对象。

由于 struct 标记和 typedef 名称位于不同的命名空间中(不要与 C++ 命名空间混淆),因此它们无需区分。对两者使用相同的标识符是完全可以接受的:

typedef struct PersonalData {
    /* ... */
    struct PersonalData *next;
} PersonalData;

或者,只要您将同时拥有标签和 typedef,您就可以转发声明 typedef:

typedef struct PersonalData PersonalData;
/* At this point, "struct PersonalData is an incomplete type. */
struct PersonalData {
    /* ... */
    PersonalData *next;
};
/* And now "struct PersonalData" is a complete type. */

(但拼写错误可能会给您留下一个typedef仍然指代从未完成的不完整类型,这可能会引发难以追踪的错误。复制和粘贴是您的朋友。)

还有另一种选择。您定义的类型已经有一个名称:struct PersonalData。所做的typedef只是给同一个类型一个不同的名字。能够使用单个标识符作为类型名称很好,但实际上没有必要。我自己的偏好是typedef完全省略,而只是将类型称为struct PersonalData

struct PersonalData {
    /* ... */
    struct PersonalData *next;
};
struct PersonalData *head;
struct PersonalData fred;

除非PersonalData是一种不透明类型(意味着使用它的代码不需要知道它是一个结构),否则显式有一些优势。

很多人在这一点上强烈反对我,并且非常喜欢将 typedef 用于结构,正如您可能会在评论中看到的那样。像这样使用 typedef 并没有错;这只是没有必要。你应该准备好阅读其他人使用任何一种风格编写的代码。

于 2013-10-10T04:10:29.857 回答