c中结构的原型

prototype of a struct in c

我想用 c 来组织我的代码,所以它的工作方式有点像 c++ 中的 publicprivate 关键字

具体来说,我有一些函数将在其他项目中用作库,我想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

无效

如您所见,在这两种情况下(AB),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;
}