【问题标题】:using the typedef keyword with a struct使用带有结构的 typedef 关键字
【发布时间】:2017-11-15 02:19:42
【问题描述】:

将 typedef 与 struct 一起使用并给它两个名称(通常是大写字母)的目的到底是什么?

今天我在看一个winsock教程,偶然发现了下面的结构体定义。

// IPv4 AF_INET sockets:
struct sockaddr_in {
    short            sin_family;   // e.g. AF_INET, AF_INET6
    unsigned short   sin_port;     // e.g. htons(3490)
    struct in_addr   sin_addr;     // see struct in_addr, below
    char             sin_zero[8];  // zero this if you want to
};

typedef struct in_addr {
  union {
    struct {
      u_char s_b1,s_b2,s_b3,s_b4;
    } S_un_b;
    struct {
      u_short s_w1,s_w2;
    } S_un_w;
    u_long S_addr;
  } S_un;
} IN_ADDR, *PIN_ADDR, FAR *LPIN_ADDR;


struct sockaddr {
    unsigned short    sa_family;    // address family, AF_xxx
    char              sa_data[14];  // 14 bytes of protocol address
};

这条线具体是做什么的?

IN_ADDR, *PIN_ADDR, FAR *LPIN_ADDR;

【问题讨论】:

  • 它正在创建一种与struct in_addr 同义的类型和两种指向该类型的指针类型。
  • 请不要用typedef指针,如*PIN_ADDR, FAR *LPIN_ADDR
  • 对于 typedef 一个 struct 其唯一成员是 union 来说似乎很奇怪。为什么不只是typedef union
  • typedef 中隐藏指针对我来说是一种非常糟糕的做法。

标签: c struct


【解决方案1】:

将 typedef 与 struct 一起使用并给它两个名称(通常是大写字母)的目的到底是什么?

三个主要组成部分

typedef struct in_addr {
    // members ... 
} IN_ADDR, *PIN_ADDR, FAR *LPIN_ADDR;
  • 正在声明的几个标识符:IN_ADDRPIN_ADDRLPIN_ADDR。就 C 而言,它们大写的事实没有任何意义;这大概是所选编码风格的一个方面。

  • 为这些标识符声明的类型分别为struct in_addrstruct in_addr *struct in_addr FAR *。类型声明还包含struct in_addr 类型的定义,这是可选的,因为给出了结构标记 (in_addr)。定义可以单独给出或根本不给出:

    typedef struct in_addr IN_ADDR, *PIN_ADDR, FAR *LPIN_ADDR;
    
    struct in_addr {
        // members ...
    };
    
  • 声明的存储类typedef,它表示这些标识符不是引用具有关联存储的对象,而是用作其声明类型的别名。

总体而言,该语句将IN_ADDRPIN_ADDRLPIN_ADDR 声明为三种不同但相关的类型的别名。

【讨论】:

    【解决方案2】:

    这将创建IN_ADDR, *PIN_ADDR, FAR *LPIN_ADDR 类型,它们与struct in_addr 同义,而struct in_addr 又指给定的结构定义。当您想对带有自引用的结构进行类型定义,但又不想在每个声明之前添加 struct 关键字时,这种做法很有用::

    typedef struct _SomeStruct_t{
        int                    someVal;
        struct _SomeStruct_t  *pNext;
    } SomeStruct_t;
    
    SomeStruct_t  gSomeStruct;
    

    您不能将 pNext 设置为指向 SomeStruct_t 的指针,因为此时尚未定义它,因此您可以改用 struct _SomeStruct_t

    【讨论】:

    【解决方案3】:

    您使用 typedef 为 struct 类型创建一个别名,这样您下次想要使用它时就不必完全输入它。如果你没有 typedef,任何时候你想使用in_addr 都必须将它声明为struct in_addr。 typedef 允许您将其声明为IN_ADDR。当 typedefed 名称没有星号时,它会为该类型创建一个别名,并且一个名称前面有一个星号,如 *IN_ADDR 为指向该类型的指针创建一个别名,因此您可以编写 PIN_ADDR 而不是struct in_addr*.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-08
      相关资源
      最近更新 更多