Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 在头文件中声明结构_C_Declaration - Fatal编程技术网

C 在头文件中声明结构

C 在头文件中声明结构,c,declaration,C,Declaration,我在我的fifo.c文件中有类型fifo\u t定义,如下所示。在头文件中,这种类型的声明应该是什么?我想使此结构的内容仅在文件fifo.c中已知。此外,我不想通过struct struct\u name var创建此结构的实例。唯一有效的方法应该是fifo\t var typedef struct { uint8_t *buffer, uint8_t indexRead, uint8_t indexWrite, uint8_t used, uint8_t

我在我的fifo.c文件中有类型
fifo\u t
定义,如下所示。在头文件中,这种类型的声明应该是什么?我想使此结构的内容仅在文件fifo.c中已知。此外,我不想通过
struct struct\u name var创建此结构的实例。唯一有效的方法应该是
fifo\t var

typedef struct {
    uint8_t *buffer,
    uint8_t indexRead,
    uint8_t indexWrite,
    uint8_t used,
    uint8_t size
} fifo_t;

如果希望能够像
fifo\u t var一样在堆栈上创建它,则不能隐藏
fifo\u t
的内容因为
大小(fifo\t)
未知

您可以在标题中对
fifo\t
执行forvard声明:
struct fifo\t。在其他文件中,您将能够创建指向
fifo\u t
的poiner,并使用应该在fifo.c中实现的函数来处理它们

fifo_t *var;
create(&var);
do_work(var);
destroy(var);

如果希望能够像
fifo\u t var一样在堆栈上创建它,则不能隐藏
fifo\u t
的内容因为
大小(fifo\t)
未知

您可以在标题中对
fifo\t
执行forvard声明:
struct fifo\t。在其他文件中,您将能够创建指向
fifo\u t
的poiner,并使用应该在fifo.c中实现的函数来处理它们

fifo_t *var;
create(&var);
do_work(var);
destroy(var);

如果您只想传递指向
fifo\t
的指针,那么您只能在头文件中转发声明它。但是,未命名结构的
typedef
仅在定义结构的内容时有效。因此,如果您不想要
struct fifo\t var要编译,您必须使用一些违反直觉的名称,例如
fifo\u t\u
。例如:

typedef struct fifo_t_ fifo_t;
void fifo_use(fifo_t*); // ok, just uses pointer
然后在
.c
文件中,执行(请注意,使用逗号分隔成员是无效的语法):

另外,请注意
fifo\t var不起作用,因为您需要知道结构的大小才能为其分配空间。您可以做的是,以对用户透明的方式在内部使用指针:

// in .h file:

typedef struct fifo_t_* fifo_t;

void fifo_init(fifo_t*);
void fifo_free(fifo_t);
void fifo_use(fifo_t);

// in .c file:

struct fifo_t_{
    uint8_t *buffer;
    uint8_t indexRead;
    uint8_t indexWrite;
    uint8_t used;
    uint8_t size;
};

void fifo_init(fifo_t* f) {
    *f = (fifo_t)malloc(sizeof(struct fifo_t_));
}

void fifo_free(fifo_t f) {
    free(f);
}

void fifo_use(fifo_t f) {
    f->indexRead = 1;
}


// somewhere else

int main() {
    fifo_t fifo;
    fifo_init(&fifo);
    fifo_use(fifo);
    fifo_free(fifo);
}

如果您只想传递指向
fifo\t
的指针,那么您只能在头文件中转发声明它。但是,未命名结构的
typedef
仅在定义结构的内容时有效。因此,如果您不想要
struct fifo\t var要编译,您必须使用一些违反直觉的名称,例如
fifo\u t\u
。例如:

typedef struct fifo_t_ fifo_t;
void fifo_use(fifo_t*); // ok, just uses pointer
然后在
.c
文件中,执行(请注意,使用逗号分隔成员是无效的语法):

另外,请注意
fifo\t var不起作用,因为您需要知道结构的大小才能为其分配空间。您可以做的是,以对用户透明的方式在内部使用指针:

// in .h file:

typedef struct fifo_t_* fifo_t;

void fifo_init(fifo_t*);
void fifo_free(fifo_t);
void fifo_use(fifo_t);

// in .c file:

struct fifo_t_{
    uint8_t *buffer;
    uint8_t indexRead;
    uint8_t indexWrite;
    uint8_t used;
    uint8_t size;
};

void fifo_init(fifo_t* f) {
    *f = (fifo_t)malloc(sizeof(struct fifo_t_));
}

void fifo_free(fifo_t f) {
    free(f);
}

void fifo_use(fifo_t f) {
    f->indexRead = 1;
}


// somewhere else

int main() {
    fifo_t fifo;
    fifo_init(&fifo);
    fifo_use(fifo);
    fifo_free(fifo);
}

如果您确实想在fifo.h中定义结构,这是一种方法:

fifo.h

... 
#ifdef FIFO
 typedef struct {
    uint8_t *buffer,
    uint8_t indexRead,
    uint8_t indexWrite,
    uint8_t used,
    uint8_t size
} fifo_t;
#else
...
#endif
...
fifo.c

#define FIFO
#include "fifo.h"
...

因此,fifo.h仍然可以包含在其他源文件中,但结构类型是隐藏的,只有使用fifo.c

才能在fifo.h中定义结构,这是一种方法:

#define FIFO
#include "fifo.h"
...
fifo.h

... 
#ifdef FIFO
 typedef struct {
    uint8_t *buffer,
    uint8_t indexRead,
    uint8_t indexWrite,
    uint8_t used,
    uint8_t size
} fifo_t;
#else
...
#endif
...
fifo.c

#define FIFO
#include "fifo.h"
...

因此,fifo.h仍然可以包含在其他源文件中,但结构类型是隐藏的,它仅在fifo.c

中可见。您不能对原始的
结构本身执行此操作。您可以为指向
结构的不透明指针创建
typedef
?可以接受吗?实际上,您不能声明
fifo\t变量
在没有完整结构定义的其他代码中,因为其他代码没有足够的信息来留出足够的内存来保存它。如果您希望只在特定的源文件中知道该结构,为什么不直接在源文件而不是头文件中定义它呢?如果您只需要少数源文件中的结构,而不是大多数源文件中的结构,那么可以选择创建一个新的“private”头文件(例如
fifo_private.h
)包含此结构的文件。@ShadowRanger:Typedef'ing指针是个坏主意。@Olaf:当指针是仅由API函数创建、销毁和使用的数据的不透明句柄时?没有那么多。当指针在逻辑上不是指针,并且用户无法直接访问它所引用的数据时,隐藏它作为指针的标识是可以的。对于原始
struct
本身,您无法做到这一点。您可以为指向
结构的不透明指针创建
typedef
?可以接受吗?实际上,您不能声明
fifo\t变量
在没有完整结构定义的其他代码中,因为其他代码没有足够的信息来留出足够的内存来保存它。如果您希望只在特定的源文件中知道该结构,为什么不直接在源文件而不是头文件中定义它呢?如果您只需要少数源文件中的结构,而不是大多数源文件中的结构,那么可以选择创建一个新的“private”头文件(例如
fifo_private.h
)包含此结构的文件。@ShadowRanger:Typedef'ing指针是个坏主意。@Olaf:当指针是仅由API函数创建、销毁和使用的数据的不透明句柄时?没有那么多。当指针在逻辑上不是指针,并且用户无法直接访问它所引用的数据时,可以隐藏它作为指针的标识
而不是abscurate
struct
pointer。@问题是,这样您就可以传入任何内容,并且会失去某种程度的类型安全性。结构名称中不需要尾随下划线,结构名称与联合一起位于单独的命名空间中。例如,
typedef结构fifo\u t fifo\t可以正常工作。我也会再次提出建议
#define FIFO
#include "fifo.h"
...