Вы не можете объявить переменную или поле как структуру без предварительного определения структуры. Это потому, что компилятору нужно знать его размер (и смещения полей, если вы их используете), а для этого требуется определение.
Однако объявление указателей на структуру, которая не была определена, совершенно хорошо, так как компилятор знает размер указателя. Поэтому, когда желательно иметь непрозрачный тип, можно использовать интерфейс, основанный на указателях на структуру, поскольку это избавляет от необходимости определять структуру в файле заголовка.
Например,
object.h
:
#ifndef __OBJECT_H
#define __OBJECT_H
typedef struct Object Object;
Object* Object_new(int key, int val);
void Object_delete(Object* object);
int Object_get_key(const Object* object);
int Object_get_val(const Object* object);
int Object_is_smaller(const Object* x, const Object* y);
#endif
object.c
:
#include <stdlib.h>
#include "object.h"
struct Object {
int key;
int val;
};
Object* Object_new(int key, int val) {
Object* object = malloc(sizeof(Object));
if (!object)
return NULL;
object->key = key;
object->val = val;
return object;
}
void Object_delete(Object* object) {
free(object);
}
int Object_get_key(const Object* object) { return object->key; }
int Object_get_val(const Object* object) { return object->val; }
int Object_is_smaller(const Object* x, const Object* y) { return x->key < y->key; }
Пример пользователя:
#include <stdio.h>
#include "object.h"
int main(void) {
Object* object = Object_new(4, 5);
printf("%d: %d\n",
Object_get_key(object),
Object_get_val(object)
);
Object_delete(object);
return 0;
}