简体   繁体   English

Typedef struct错误的声明?

[英]Typedef struct wrong declaration?

I referred to the tutorial below and later realized it is wrong way of declaring struct using typedef. 我参考了下面的教程,后来意识到使用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 这是教程http://www.iu.hio.no/~mark/CTutorial/CTutorial.html

There's nothing formally "incorrect" about either approach. 两种方法都没有正式的“不正确”之处。

The former declares a tag-less struct type and a typedef name PersonalData for that struct type. 前者声明一个无标签的结构类型,并为该结构类型声明typedef名称PersonalData The latter declares a struct type struct personaldataStruct and a synonymous typedef name PersonalData for that struct type. 后者声明了一个结构类型struct personaldataStruct和该结构类型的同义typedef名称PersonalData The personaldataStruct part of the declaration is commonly referred as a "struct tag". 声明的personaldataStruct部分通常称为“结构标签”。

As long as you use PersonalData typedef name for referring to that struct type, as in 只要您使用PersonalData typedef名称来引用该结构类型,如

PersonalData x;

you will not see any difference between the two declarations. 您将不会看到两个声明之间的任何区别。 In both cases x will be declared identically. 在两种情况下, x都将声明为相同。

The latter approach provides you with an alternative way of referring to the same struct type - struct personaldataStruct - if for some reason you will wish to do so. 后一种方法为您提供了另一种引用相同结构类型的方法struct personaldataStruct如果出于某些原因您希望这样做。 Eg when using the latter declaration, you can also declare your x as 例如,使用后一个声明时,您还可以将x声明为

struct personaldataStruct x;

which is exactly equivalent to the PersonalData x; 完全等同于PersonalData x; declaration. 宣言。

Personally, I prefer to use the approach with struct tag, since it provides me with alternative way of referring to the type, which might come handy in some situations (for example, when the struct type has to refer to itself). 就我个人而言,我更喜欢将这种方法与struct标签一起使用,因为它为我提供了另一种引用类型的方式,这种方式在某些情况下可能会派上用场(例如,当struct类型必须引用自身时)。 But in most non-self-referential cases one will be perfectly fine with the former approach. 但是在大多数非自我引用的情况下,使用前一种方法将是完美的。

Both are correct. 两者都是正确的。 The only real problem with the first form (without the tag) is that, because the typedef name doesn't become visible until the end of the definition, there's no way to refer to the structure from within its own definition. 第一种形式(不带标签)唯一真正的问题是,由于typedef名称直到定义末尾才可见,因此无法从其自身的定义中引用该结构。 That's a common requirement; 这是一个普遍的要求; for example, a node in a linked list, tree, or other graph-like data structure commonly needs to point to other objects of the same type. 例如,链表,树或其他类似图的数据结构中的节点通常需要指向相同类型的其他对象。

Since struct tags and typedef names are in different namespaces (not to be confused with C++ namespaces), there's no need for them to be distinct. 由于struct标记和typedef名称位于不同的命名空间中 (不要与C ++命名空间混淆),因此无需将它们区分。 It's perfectly acceptable to use the same identifier for both: 对两个都使用相同的标识符是完全可以接受的:

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

Or, as long as you're going to have both a tag and a typedef anyway, you can forward declare the typedef: 或者,只要您将同时拥有标签和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. */

(But a misspelling can leave you with a typedef that still refers to an incomplete type that's never completed, which can trigger errors that can be difficult to track down. Copy-and-paste is your friend.) (但是,拼写错误可能会给您留下一个typedef ,它仍然引用从未完成的不完整类型,这会触发可能难以跟踪的错误。复制粘贴是您的朋友。)

And there is another alternative. 还有另一种选择。 The type you've defined already has a name: struct PersonalData . 您定义的类型已经有一个名称: struct PersonalData All the typedef does is give that same type a different name. typedef所做的只是为同一类型赋予不同的名称。 It's nice to be able to use a single identifier as a type name, but it's really not necessary. 能够将单个标识符用作类型名称是很好的做法,但实际上不是必需的。 My own preference is to omit the typedef altogether, and just refer to the type as struct PersonalData : 我自己的偏好是完全省略typedef ,仅将类型称为struct PersonalData

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

Unless PersonalData is meant to be an opaque type (meaning that code that uses it doesn't need to know that it's a struct), there's some advantage in being explicit. 除非将PersonalData为不透明类型(意味着使用它的代码不需要知道它是结构),否则显式会有一些优势。

Plenty of people strongly disagree with me on this point, and really like using typedefs for structures, as you'll probably see in comments. 在这一点上,很多人强烈不同意我的观点,并且真的很喜欢对结构使用typedef,就像您可能会在评论中看到的那样。 There's nothing wrong with using typedefs like this; 像这样使用typedef并没有错。 it's just not necessary. 只是没有必要。 You should be prepared to read code written by others using either style. 您应该准备好阅读使用其他任何一种风格编写的代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM