Технически, вы должны рассматривать инструкцию препроцессора #include
как инструкцию «копировать и вставить».
В основном это означает, что конечным результатом является один файл, содержащий весь текст в заказе
Конечно, в этом случае у вас есть ошибка в вашем коде, поскольку SIZE
определяется только после .
Учтите, в stack.c
:
#define SIZE 100
#include "stack.h"
Это позволило бы использовать SIZE
в stack.h
.
Кроме того, не определяя SIZE
в заголовке (по крайней мере, в качестве запасного значения). ), вы не сможете нигде включить заголовок, не указав сначала SIZE
.
Рассмотрите в заголовке добавление:
#ifndef SIZE
#define SIZE 10
#endif
ИМХО, такой подход неидеальный способ использовать эту возможность, но это должно ответить на ваш вопрос.
Наилучшим подходом будет, IMHO, использование неполного типа или «гибкого массива».
Например,Вы можете определить тип, используя:
typedef struct stack{
int current_size;
Item array[];
} Stack;
Затем выделите достаточно памятиМожно управлять размером стека с помощью (например):
Stack * s = malloc(sizeof(*s) + (SIZE*sizeof(Item)));
Однако я, вероятно, предпочел бы сделать тип непрозрачным указателем.
Это означает, что данные будут доступны только при использованиифункции.
Использование непрозрачного указателя обеспечило бы гораздо более сильное разделение.
Это также полезно, позволяя обновлять тип данных в будущем без нарушения совместимости ABI / обратной совместимости.
то есть, в заголовке ограничьте себя:
typedef struct stack Struct;
Функции будут использовать указатель на неполный тип.
Stack *create_stack(void);
Это обещает, что никто, использующий заголовок, не сможетдоступ к данным (они получат ошибку при доступе к неполному типу).
Файл C определит структуру только для внутреннего использования:
struct stack{
Item array[SIZE];
int current_size;
};
Или, используя динамический размерПодход, как отмечалось выше:
struct stack{
int current_size;
Item array[];
};
Stack *create_stack(size_t size)
{
Stack * s = malloc(sizeof(*s) + (size * sizeof(*s->array)));
// ....
return s;
}
PS - IMHO
В качестве примечания о наименовании ... вы, похоже, используете соглашение об именовании CamelCase.
В Си вы обнаружите, что большинство разработчиков склонны называть вещи, используя snake_case, а не CamelCase.
Кроме того, typedefs часто имеют суффикс, подобный суффиксу (зарезервированный) _t
, используемому в POSIX и некоторых стандартныхтипы (т. е. типы структур могут заканчиваться _s
).
Это всего лишь мое личное мнение , но, как считыватель длинного кода, мне легче читать код, который соответствуетстиль стандартной библиотеки, предоставляемый языком. Очевидно, что не все согласны со мной.
Используя эти соглашения об именах, я бы назвал эти типы как:
typedef int item_i;
typedef struct stack{
int current_size;
item_i array[SIZE];
} stack_s;