【问题标题】:C Typedef and Struct QuestionC Typedef和结构问题
【发布时间】:2009-07-10 17:37:43
【问题描述】:

这两种声明有什么区别,一种优于另一种?

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

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

【问题讨论】:

    标签: c struct namespaces typedef


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

      struct foo { int bar; };
      

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

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

      此外,您可以像这样在定义中立即实例化一个新对象:

      struct foo { int bar; } baz;
      

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

      typedef struct foo { int bar; } baz;
      

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

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

      【讨论】:

        【解决方案3】:

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

        您可以获得一些小好处:

        • struct STRUCTNAME”可用于在结构中声明指向结构的指针
        • 您只需在 C 或 C++ 代码中使用 STRUCTNAME 即可摆脱困境
        • 您可以防止 C++ 中潜在的(即使在实践中非常罕见)怪异与用于另一个对象的结构名称有关,而不会出现错误或警告

        但是,如果我碰巧手动输入了结构定义,我经常会懒惰地忽略声明一个或另一个名称。

        【讨论】:

          【解决方案4】:

          第一个示例允许您将对象内部用于链接列表和树(如Victor points out)。第二个是匿名类型的一个例子,经验表明它在所有编译器中都表现不佳。所以可能推荐第一种方法。如果您不关心结构是否能够引用自身,您始终可以给它起一个不太可能发生冲突的名称,例如 __SOMEPREFIX_IOPORT__。

          【讨论】:

          • 以双下划线或下划线+大写字母开头的标识符是保留的,所以你不应该使用它们。它们可能与编译器或标准库中的标识符冲突。见stackoverflow.com/a/1449301
          【解决方案5】:

          为了便于阅读,最好以如下形式表达原始示例:

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

          ....强调类型和实例的区别。

          此外,如果您想添加初始化程序,您可以执行以下操作:

          typedef struct IOPORT_t {  
              GPIO_TypeDef* port;  
              u16           pin;  
          } IOPORT;
          
          struct IOPORT_t IOPORT2 = {
              .port = NULL,
              .pin = 25
            };
          

          或者你可以丢失typedef直接初始化它:

          struct IOPORT_t {  
              GPIO_TypeDef* port;  
              u16           pin;  
          } IOPORT = {
              .port = NULL,
              .pin = 24
            };
          
          struct IOPORT_t IOPORT2 = {
              .port = NULL,
              .pin = 25
            };
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-03-24
            • 1970-01-01
            • 2013-03-29
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多