C Typedef和Struct问题

这两个声明之间的区别是什么,并且优先于另一个?

typedef struct IOPORT { GPIO_TypeDef* port; u16 pin; } IOPORT; typedef struct { GPIO_TypeDef* port; u16 pin; } IOPORT; 

至于首选哪种样式,我更喜欢第一种样式(结构标记中的名称和结构的typedef),因为除了源文件中的更多字符之外没有任何缺点。 我的IDE的struct snippet在两个地方都删除了名称,所以我总是得到一个typedef’ed结构名称和一个struct标签名称。

你会得到一些小的好处:

  • struct STRUCTNAME ”可用于声明指向struct中结构的指针
  • 只需在C或C ++代码中使用STRUCTNAME就可以逃脱
  • 你可以防止C ++中的一个奇怪的东西,即在没有错误或警告的情况下将结构名称用于另一个对象

但是,如果我碰巧手动输入结构定义,我常常懒得忽略声明一个或另一个名字。

第一个允许您在结构中使用IOPORT来引用相同类型的对象。 在链接列表等情况下非常有用,其中节点必须引用节点。

C有四个不同的命名空间,其中结构标记命名空间就是其中之一。 因此:

 struct foo { int bar; }; 

一般意义上没有定义新类型。 当你只有一个结构标记时,你需要在对象声明中添加关键字’struct’,如下所示:

 foo b; /* error */ struct foo b; /* correct */ 

此外,您可以在定义中立即实例化一个新对象,如下所示:

 struct foo { int bar; } baz; 

其中baz是结构类型为foo的对象。 但是,人们经常希望将结构定义为新类型,以节省一些写作。 完整类型不引用结构标记,因此您可以在声明期间省略’struct’前缀。

 typedef struct foo { int bar; } baz; 

仍然允许您使用’struct foo’声明对象,因为foo是struct标记。 但现在它被提升为“普通”类型命名空间中的完整类型,其中它被称为类型baz。 因此,对于typedef,’baz’字段具有不同的语义。

除非您需要在其自身内部声明指向结构类型的指针(链接列表,树结构),否则请省略它。 添加一个不需要的只会污染命名空间。

第一个例子允许你使用内部的对象来链接列表和树(就像Victor指出的那样 )。 第二个是匿名类型的一个例子,经验告诉我们所有编译器都不能很好地表现出来。 所以可能推荐第一种方法。 如果您不关心结构能够引用自身,您总是可以给它一个不太可能像__SOMEPREFIX_IOPORT__那样冲突的名称。