c中结构的原型
prototype of a struct in c
我想用 c 来组织我的代码,所以它的工作方式有点像 c++ 中的 public
和 private
关键字
具体来说,我有一些函数将在其他项目中用作库,我想public
只做项目使用的函数,而不是内部必须的函数动作
如果我能把他们都放在同一个地方会很容易file.c,但我的学校规定不允许我这样做
我希望举个例子很清楚:
(A) struct definition (B) struct definition
in header.h in second_file.c
+----------------------+ +----------------------+
| header.h | | header.h |
------------------------ ------------------------
| #ifndef HEADER_H | | #ifndef HEADER_H |
| # define HEADER_H | | # define HEADER_H |
| | | |
| typedef struct foo | | |
| { | | |
| type param_1; | | |
| type param_2; | | |
| } t_foo; | | |
| | | |
| void action_a(void); | | void action_a(void); |
| void action_b(void); | | void action_b(void); |
| | | |
| #endif | | #endif |
+----------------------+ +----------------------+
+----------------------+ +----------------------+
| first_file.c | | first_file.c |
------------------------ ------------------------
| # include header.h | | #include header.h |
| | | |
| // prototypes | | // prototypes |
| void utils_a(void); | | void utils_a(void); |
| void utils_b(void); | | void utils_b(void); |
| | | |
| | | // struct prototype |
| | | t_foo; |
| | | |
| void action_a(void){ | | void action_a(void){ |
| // do something; | | // do something; |
| // use t_foo; | | // use t_foo; |
| } | | } |
| void action_b(void){ | | void action_b(void){ |
| // do something; | | // do something; |
| } | | } |
+----------------------+ +----------------------+
+----------------------+ +----------------------+
| second_file.c | | second_file.c |
------------------------ ------------------------
| # include header.h | | #include header.h |
| | | |
| | | typedef struct foo |
| | | { |
| | | type param_1; |
| | | type param_2; |
| | | } t_foo; |
| | | |
| void utils_a(void) { | | void utils_a(void) { |
| // do something; | | // do something; |
| // use t_foo; | | // use t_foo; |
| } | | } |
| void utils_b(void) { | | void utils_b(void) { |
| // do something; | | // do something; |
| } | | } |
+----------------------+ +----------------------+
case A
有效,但 case B
无效
如您所见,在这两种情况下(A
和 B
),header 不包含 utils 函数,它们不能被其他函数使用(除非它们包括原型本身),header 不包括它们
我想对结构做同样的事情(它在两个files.c中都使用),因为这个结构只是函数的一个实用程序,没有在其他地方调用的目的
使用评论中的解决方案编辑一个工作示例,但它不起作用(编译给我一个错误)
header.h
#ifndef HEADER_H
# define HEADER_H
#include <stdlib.h> // malloc()
#include <stdio.h> // printf()
// CASE A ONLY
// typedef struct foo {
// int param;
// } t_foo;
// CASE A END
// CASE B ONLY
typedef struct foo t_foo;
// CASE B END
t_foo **allocate_foo(void);
#endif
first_file.c
#include "header.h"
int main(void)
{
t_foo **tfoo;
tfoo = allocate_foo();
(*tfoo)->param = 1;
printf("%i\n", (*tfoo)->param);
return (0);
}
second_file.c
#include "header.h"
// CASE B ONLY
struct foo {
int param;
};
// CASE B END
t_foo **allocate_foo(void)
{
static t_foo *tfoo;
tfoo = malloc(sizeof(t_foo));
return (&tfoo);
}
情况 A 编译正常并打印 1
,但情况 B 在编译时抛出错误:
first_file.c: In function ‘main’:
first_file.c:8:9: error: dereferencing pointer to incomplete type ‘t_foo {aka struct foo}’
(*tfoo)->param = 1;
^~
通常最基本的解决方案是使 public 成为结构类型标识符,但将定义保持私有......又名 opaque pointer ...类似于 FILE
/* library.h */
#ifndef LIBRARY_H_INCLUDED
#define LIBRARY_H_INCLUDED
struct foo; // struct foo exists; it's definition is elsewhere
struct foo *newfoo(int);
void printfoo(struct foo *);
void killfoo(struct foo *);
#endif // LIBRARY_H_INCLUDED
/* library.c */
#include <stdio.h>
#include <stdlib.h>
#include "library.h"
struct foo { int bar; }; // struct foo has a single member
struct foo *newfoo(int n) {
struct foo *r = malloc(sizeof *r);
if (r) r->bar = n;
return r;
}
void printfoo(struct foo *s) {
printf("%d\n", s->bar);
}
void killfoo(struct foo *s) {
free(s);
}
/* main.c */
#include "library.h"
int main(void) {
struct foo *p = newfoo(42);
if (p) {
printfoo(p);
killfoo(p);
}
return 0;
}
我想用 c 来组织我的代码,所以它的工作方式有点像 c++ 中的 public
和 private
关键字
具体来说,我有一些函数将在其他项目中用作库,我想public
只做项目使用的函数,而不是内部必须的函数动作
如果我能把他们都放在同一个地方会很容易file.c,但我的学校规定不允许我这样做
我希望举个例子很清楚:
(A) struct definition (B) struct definition
in header.h in second_file.c
+----------------------+ +----------------------+
| header.h | | header.h |
------------------------ ------------------------
| #ifndef HEADER_H | | #ifndef HEADER_H |
| # define HEADER_H | | # define HEADER_H |
| | | |
| typedef struct foo | | |
| { | | |
| type param_1; | | |
| type param_2; | | |
| } t_foo; | | |
| | | |
| void action_a(void); | | void action_a(void); |
| void action_b(void); | | void action_b(void); |
| | | |
| #endif | | #endif |
+----------------------+ +----------------------+
+----------------------+ +----------------------+
| first_file.c | | first_file.c |
------------------------ ------------------------
| # include header.h | | #include header.h |
| | | |
| // prototypes | | // prototypes |
| void utils_a(void); | | void utils_a(void); |
| void utils_b(void); | | void utils_b(void); |
| | | |
| | | // struct prototype |
| | | t_foo; |
| | | |
| void action_a(void){ | | void action_a(void){ |
| // do something; | | // do something; |
| // use t_foo; | | // use t_foo; |
| } | | } |
| void action_b(void){ | | void action_b(void){ |
| // do something; | | // do something; |
| } | | } |
+----------------------+ +----------------------+
+----------------------+ +----------------------+
| second_file.c | | second_file.c |
------------------------ ------------------------
| # include header.h | | #include header.h |
| | | |
| | | typedef struct foo |
| | | { |
| | | type param_1; |
| | | type param_2; |
| | | } t_foo; |
| | | |
| void utils_a(void) { | | void utils_a(void) { |
| // do something; | | // do something; |
| // use t_foo; | | // use t_foo; |
| } | | } |
| void utils_b(void) { | | void utils_b(void) { |
| // do something; | | // do something; |
| } | | } |
+----------------------+ +----------------------+
case A
有效,但 case B
如您所见,在这两种情况下(A
和 B
),header 不包含 utils 函数,它们不能被其他函数使用(除非它们包括原型本身),header 不包括它们
我想对结构做同样的事情(它在两个files.c中都使用),因为这个结构只是函数的一个实用程序,没有在其他地方调用的目的
使用评论中的解决方案编辑一个工作示例,但它不起作用(编译给我一个错误)
header.h
#ifndef HEADER_H
# define HEADER_H
#include <stdlib.h> // malloc()
#include <stdio.h> // printf()
// CASE A ONLY
// typedef struct foo {
// int param;
// } t_foo;
// CASE A END
// CASE B ONLY
typedef struct foo t_foo;
// CASE B END
t_foo **allocate_foo(void);
#endif
first_file.c
#include "header.h"
int main(void)
{
t_foo **tfoo;
tfoo = allocate_foo();
(*tfoo)->param = 1;
printf("%i\n", (*tfoo)->param);
return (0);
}
second_file.c
#include "header.h"
// CASE B ONLY
struct foo {
int param;
};
// CASE B END
t_foo **allocate_foo(void)
{
static t_foo *tfoo;
tfoo = malloc(sizeof(t_foo));
return (&tfoo);
}
情况 A 编译正常并打印 1
,但情况 B 在编译时抛出错误:
first_file.c: In function ‘main’:
first_file.c:8:9: error: dereferencing pointer to incomplete type ‘t_foo {aka struct foo}’
(*tfoo)->param = 1;
^~
通常最基本的解决方案是使 public 成为结构类型标识符,但将定义保持私有......又名 opaque pointer ...类似于 FILE
/* library.h */
#ifndef LIBRARY_H_INCLUDED
#define LIBRARY_H_INCLUDED
struct foo; // struct foo exists; it's definition is elsewhere
struct foo *newfoo(int);
void printfoo(struct foo *);
void killfoo(struct foo *);
#endif // LIBRARY_H_INCLUDED
/* library.c */
#include <stdio.h>
#include <stdlib.h>
#include "library.h"
struct foo { int bar; }; // struct foo has a single member
struct foo *newfoo(int n) {
struct foo *r = malloc(sizeof *r);
if (r) r->bar = n;
return r;
}
void printfoo(struct foo *s) {
printf("%d\n", s->bar);
}
void killfoo(struct foo *s) {
free(s);
}
/* main.c */
#include "library.h"
int main(void) {
struct foo *p = newfoo(42);
if (p) {
printfoo(p);
killfoo(p);
}
return 0;
}