C Typedef和Struct问题

lon*_*ger 10 c struct typedef namespaces

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

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

typedef struct {  
    GPIO_TypeDef* port;  
    u16           pin;  
} IOPORT;  
Run Code Online (Sandbox Code Playgroud)

Vic*_*tor 16

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


小智 9

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

struct foo { int bar; };
Run Code Online (Sandbox Code Playgroud)

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

foo b; /* error */
struct foo b; /* correct */
Run Code Online (Sandbox Code Playgroud)

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

struct foo { int bar; } baz;
Run Code Online (Sandbox Code Playgroud)

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

typedef struct foo { int bar; } baz;
Run Code Online (Sandbox Code Playgroud)

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

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


Mic*_*urr 8

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

你会得到一些小的好处:

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

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