Technically, you should consider the #include
pre-processor instruction as a "copy and paste" instruction.
This basically means that the end-result is a single file containing all the text in the order specified.
Of course, in that case, you have an error in you code, since SIZE
is only defined after it's used.
Consider, in stack.c
:
#define SIZE 100
#include "stack.h"
This would allow SIZE
to be used within stack.h
.
Also, by not defining SIZE
in the header (at least as a fallback value), you will not be able to include the header anywhere without manually defining SIZE
first.
Consider, in the header, adding:
#ifndef SIZE
#define SIZE 10
#endif
IMHO, this approach isn't the ideal way to use this capability, but this should answer your question.
The best approaches would, IMHO, be to use an incomplete type or a "flexible array".
For example, you could define the type using:
typedef struct stack{
int current_size;
Item array[];
} Stack;
Then allocate enough memory to manage the stack size using (for example):
Stack * s = malloc(sizeof(*s) + (SIZE*sizeof(Item)));
However, I would probably opt for making the type an opaque pointer.
This means that data will only be accessible using the functions.
Using an opaque pointer would provide much stronger compartmentalization.
It's also helpful by allowing you to update the data type in the future without breaking ABI / backwards compatibility.
i.e., in the header limit yourself to:
typedef struct stack Struct;
The functions will use a pointer to an incomplete type.
Stack *create_stack(void);
This will promise that no one using the header could access the data (they will get an error about accessing an incomplete type).
The C file will define the struct only for it's internal use:
struct stack{
Item array[SIZE];
int current_size;
};
Or, using a dynamic size approach, as noted above:
struct stack{
int current_size;
Item array[];
};
Stack *create_stack(size_t size)
{
Stack * s = malloc(sizeof(*s) + (size * sizeof(*s->array)));
// ....
return s;
}
P.S. - IMHO
As a note about naming... you seem to be using a CamelCase naming convention.
In C, you would find that most developers tend to name things using snake_case rather than CamelCase.
Also, typedefs often have a suffix, similar to the (reserved) _t
suffix used by POSIX and some standard types (i.e., struct types might end with _s
).
The are only my personal opinions, but as a long time code reader, I find it easier to read code that matches the style of the standard library provided by a language. Obviously, not everyone agrees with me.
Using these naming conventions, I would name these types as:
typedef int item_i;
typedef struct stack{
int current_size;
item_i array[SIZE];
} stack_s;