обзор 2 различных методов определения типа структуры - PullRequest
3 голосов
/ 17 ноября 2010
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, которая является именем тега или именем самой структуры?

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 ]

4 голосов
/ 17 ноября 2010

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;

Как вы видели, в этом случае два синтаксиса в основном эквивалентны.

2 голосов
/ 17 ноября 2010
typedef struct channel_t channel_t;

Это означает, что на структуру, называемую "struct channel_t", также можно ссылаться, используя имя "channel_t".Конфликта нет, поскольку имя первого типа - "struct channel_t", а не просто "channel_t".

Что касается (2), это просто определение структуры.Строка typedef - это просто typedef, она не определяет структуру.Этот шаблон (без определения структуры в заголовке, определения структуры в источнике) обычно используется, когда вы просто хотите, чтобы API обеспечивал безопасность типов (вместо использования «void *»), без раскрытия внутренних частей структуры.

...