A complete answer will require a long, long, long answer. And it could turn into opinion based examples (which is unpopular/forbidden on SO). But below I have written a few of the many things that you new to consider.
You are mixing two unrelated things together. Using a structure (a struct
) doesn't prevent you from making the stack a global variable. Not using a structure doesn't prevent you from using local stack.
int stack_data[N]; // Global stack
int stack_size = 0; // without a struct
struct stack {
int data[N];
int size;
};
struct stack stack = {0}; // Global stack using struct
void foo(void) {
int foo_stack_data[N]; // Local stack
int foo_stack_index = 0; // without a struct
...
...
}
void bar(void) {
struct stack bar_stack = {0}; // Local stack using struct
...
...
}
In other words - whether the stack is global or local hasn't anything to do with the use of struct
.
There are several reasons for using struct
. Gathering closely related variables like "stack data" and "stack size" in a struct
will in many cases make you code easier to read and maintain.
As an example assume your program needs 100 stacks. Without the struct
you would need 2 * 100 = 200 lines of code. With a struct stack
you'll only need 100 lines (plus 4 for the definition). And this would just get worse as the number of variables related to the data structure increased.
And if you need a dynamic allocated stack a single call of malloc
would do using struct
while you would need 2 calls of malloc
without struct
.
Global variables.... hmmm, there are situations where a (few) global variables makes sense. But extensive use of global variables (nearly) always leads to a mess. A good rule is to avoid globals unless you have a very strong argument.
Look at this:
int stack_data[N]; // Global stack
int stack_size = 0; // without a struct
void push(int value) {
// error check omitted
stack_data[stack_size] = value;
stack_size = stack_size + 1;
}
void bar(void) {
push(42);
}
Well... it will work. But... what if I need two stacks or 8 stacks. Should I then write 8 version of the push
function? Doesn't sound like fun to me...
So I do:
void push(int value, int* d, int* sz) {
// error check omitted
d[*sz] = value;
*sz = *sz + 1;
}
void bar(void) {
push(42, stack_data, &stack_size);
push(65, another_stack_data, &another_stack_size);
}
Passing the stack related variable allows me to have multiple stacks.
But I had to pass both the data and the size. Two arguments. And what if I need 5 variables to describe my data structure.... then I would have to pass 5 arguments.
Besides all the typing, it would/could also hurt performance.
By using the struct
method I could do with a single argument, i.e. a pointer to a struct
variable:
void push(int value, struct stack *s) {
// error check omitted
s->data[s->size] = value;
s->size = s->size + 1;
}
void bar(void) {
struct stack stack1 = {0};
push(42, &stack1);
struct stack stack2 = {0};
push(65, &stack2);
...
}