简体   繁体   中英

using the typedef keyword with a struct

What exactly is the purpose of using a typedef together with a struct and giving it two names, often one in capital letters?

Today I was looking at a winsock tutorial and came across the struct definition below.

// 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
};

What exactly does this line do?

IN_ADDR, *PIN_ADDR, FAR *LPIN_ADDR;

What exactly is the purpose of using a typedef together with a struct and giving it two names, often one in capital letters?

There are three primary components to

 typedef struct in_addr { // members ... } IN_ADDR, *PIN_ADDR, FAR *LPIN_ADDR; 
  • several identifiers that are being declared: IN_ADDR , PIN_ADDR , and LPIN_ADDR . As far as C is concerned, there is no significance to the fact that these are capitalized; presumably that is an aspect of the chosen coding style.

  • the types being declared for those identifiers, respectively struct in_addr , struct in_addr * and struct in_addr FAR * . The type declaration additionally incorporates a definition of type struct in_addr , which is optional because a struct tag ( in_addr ) is given. The definition could have instead been given separately or not at all:

     typedef struct in_addr IN_ADDR, *PIN_ADDR, FAR *LPIN_ADDR; struct in_addr { // members ... }; 
  • the storage class of the declarations, typedef , which indicates that instead of those identifiers referring to objects with associated storage, they serve as aliases for their declared types.

Overall, then, the statement declares IN_ADDR , PIN_ADDR , and LPIN_ADDR as aliases for three different, but related, types.

This creates the types IN_ADDR, *PIN_ADDR, FAR *LPIN_ADDR , which are synonymous with struct in_addr which in turn refers to the structure definintion given. This practice is is useful when you want to typedef a structure with a self reference, but don't want to add the struct keyword before each declaration::

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

SomeStruct_t  gSomeStruct;

You can't set pNext to be a pointer to SomeStruct_t because it hasn't been defined at that point, so you use struct _SomeStruct_t instead.

You use typedef to create an alias for the struct type, so that you don't have to type it out fully the next time you want to use it. If you didn't have the typedef, any time you want to use in_addr you would have to declare it as struct in_addr . The typedef allows you to declare it as IN_ADDR . When the typedefed name does not have an asterisk, it creates an alias for the type, and a name preceded by an asterisk, as in *IN_ADDR creates an alias for a pointer to the type, so you can write PIN_ADDR instead of struct in_addr* .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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