将一个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;
答案 0 :(得分:3)
将一个typedef与一个struct一起使用并给它两个名字,通常是一个大写字母的名称究竟是什么目的?
有三个主要组成部分
typedef struct in_addr { // members ... } IN_ADDR, *PIN_ADDR, FAR *LPIN_ADDR;
正在声明的几个标识符:IN_ADDR
,PIN_ADDR
和LPIN_ADDR
。就C而言,这些资本化的事实并不重要;大概这是所选编码风格的一个方面。
分别为这些标识符声明的类型struct in_addr
,struct 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_ADDR
,PIN_ADDR
和LPIN_ADDR
声明为三种不同但相关的类型的别名。
答案 1 :(得分:1)
这会创建类型IN_ADDR, *PIN_ADDR, FAR *LPIN_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
。
答案 2 :(得分:0)
您使用typedef为结构类型创建别名,这样您下次要使用它时就不必完全键入它。如果您没有typedef,那么只要您想使用in_addr
,就必须将其声明为struct in_addr
。 typedef允许您将其声明为IN_ADDR
。当typedefed名称没有星号时,它会为该类型创建别名,并且名称前面带有星号,如*IN_ADDR
为指向该类型的指针创建别名,因此您可以编写{{1而不是PIN_ADDR
。