回顾2种不同的typedef结构的方法

时间:2010-11-17 04:45:38

标签: c struct typedef

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;

非常感谢任何建议,

2 个答案:

答案 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 *”)而不暴露结构的内部时,通常会使用此模式(标头中没有结构定义,源中的结构定义)。