I have a stack that contains two types of struct. Struct Stud and Struct Prof.
When I want to push something I created two Push functions for both structs. Although I would like it to be with one function but its ok I can bear with it.
Now to Pop. If I want to Pop a student from the Stack, do I have to make a Pop function specifically for Students only? The same with Professors?
How can I store the item if I don't know what type is it? What type must the element be, to store the item there?
Here are the structs:
struct MyStack
{
int head;
void **stack;
int size;
};
typedef struct MyStack STACK;
struct stud
{
char flag;
char fname[50];
int semester;
};
struct prof
{
char flag;
char fname[50];
char course[30];
};
Now to create the Pop function. What do type of item do I pass in the function?
int Pop(STACK *stack,int *head,??? *elem)
{
if(stack->head<=-1)
return 0;
*elem=stack->stack[*head];
*head--;
return 1;
}
You have to encode the type information when you push, simplest is probably to type tag:
#define STUD 0
#define PROF 1
struct stack_entry {
int type;
void *item;
};
struct MyStack
{
int head;
struct stack_entry *stack;
int size;
};
Then change your push functions to attach the right tag when you push. Then, in pop, simplest again is probably to just return a stack_entry struct, and let the calling function figure it out. At that point you might want a snazzier name than "stack_entry" though. Also, it would be slightly preferable to use a union:
struct stack_entry {
int type;
union {
struct stud *stud;
struct prof *prof;
} item;
}
Because then the compiler can help you out a bit, but of course you still have to be more or less as careful as you would be with a void *.
Edit: initialization...
You don't have to mark then end of the buffer with anything, since you have a size variable in the struct. But if you wanted to do that I would have that be its own type
#define END_OF_BUFFER 1
#define STUD 2
#define PROF 3
And then for init you could do:
stack->size = size;
stack->stack = calloc(sizeof(*stack->stack), size + 1);
stack->stack[size].type = END_OF_BUFFER;
stack->head=-1;
Though I tend to use "head" to refer to a pointer that points to the next place to write to, but I'm not sure how standard that is. But the buffer is an array of strack_entries, not void *'s.