gcc 4.4.4 c89
使用结构体隐藏实现文件中的元素时,我总是做以下事。
port.h头文件
struct port_tag;
struct port_tag* open_ports(size_t port_id);
void close_ports(struct port_tag *port);
port.c实现文件
#include "port.h"
typedef struct port_tag {
size_t port_id;
} port_t;
port_t* open_ports(size_t port_id)
{
port_t *port = malloc(sizeof *port);
if(port == NULL) {
return NULL;
}
port->port_id = port_id;
return port;
}
void close_ports(port_t *port)
{
if(port != NULL) {
free(port);
}
}
driver.c驱动程序文件
#include "port.h"
int main(void)
{
size_t i = 0;
struct port_tag *port = NULL;
for(i = 0; i < 5; i++) {
port = open_ports(i);
if(port == NULL) {
fprintf(stderr, "Port [ %d ] failed to open\n", i);
}
close_ports(port);
}
return 0;
}
在上面的代码中,很明显标签名称是port_tag,实际的typedef名称是port_t。
但是,我正在重新设计一些代码。而且我发现他们使用了一种我从未见过的不同方法。我对他们的方法有几个问题。
channel.h头文件
typedef struct channel_t channel_t;
channel_t* open_channels(size_t channel_id);
void close_channels(channel_t *channel);
channel.c实施文件
#include "channel.h"
struct channel_t {
size_t channel_id;
};
channel_t* open_channels(size_t channel_id)
{
channel_t *channel = malloc(sizeof *channel);
if(channel == NULL) {
return NULL;
}
channel->channel_id = channel_id;
return channel;
}
void close_channels(channel_t *channel)
{
if(channel != NULL) {
free(channel);
}
}
driver.c驱动程序文件
#include "channel.h"
int main(void)
{
size_t i = 0;
channel_t *channel = NULL;
for(i = 0; i < 5; i++) {
channel = open_channels(i);
if(channel == NULL) {
fprintf(stderr, "Channel [ %zu ] failed to open\n", i);
}
close_channels(channel);
}
return 0;
}
1)当他们声明了typedef'ed结构时,它是标签名称或者名称 结构本身?
typedef struct channel_t channel_t;
2)在实现文件中,结构名称不应该跟随最后一个大括号吗?
struct channel_t <-- tag name {
size_t channel_id;
} <-- itsn't this the name of the typedef'ed struct;
非常感谢任何建议,
答案 0 :(得分:4)
1。结构类型为struct channel_t
,新的typedef为channel_t
。
这意味着它现在可以用作:
channel_t some_instance;
2。他们在其他地方创建了一个typedef,而不是在这里。所以:
struct channel_t {
size_t channel_id;
};
确定了一个带有标记channel_t
的结构类型。定义struct
时不需要typedef。它可以用作例如:
struct channel_t some_instance;
正如您所见,在这种情况下,这两种语法基本相同。
答案 1 :(得分:2)
typedef struct channel_t channel_t;
这意味着也可以使用名称“channel_t”来引用名为“struct channel_t”的结构。没有冲突,因为前一种类型的名称是“struct channel_t”而不仅仅是“channel_t”。
至于(2),那只是定义结构。 typedef行只是一个typedef,它没有定义结构。当您只希望API提供类型安全性(而不是使用“void *”)而不暴露结构的内部时,通常会使用此模式(标头中没有结构定义,源中的结构定义)。