问题描述
我有一个包含两种类型结构的堆栈.Struct Stud 和 Struct Prof.当我想推送一些东西时,我为两个结构创建了两个 Push 函数.虽然我希望它只有一个功能,但没关系,我可以忍受.
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?
这里是结构:
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];
};
现在创建 Pop 函数.我在函数中传递什么类型的项目?
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;
}
推荐答案
推送的时候需要对类型信息进行编码,最简单的大概就是输入tag:
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;
};
然后更改您的推送功能以在您推送时附加正确的标签.然后,在 pop 中,最简单的可能就是返回一个 stack_entry 结构,并让调用函数计算出来.那时你可能想要一个比stack_entry"更时髦的名字.另外,最好使用联合:
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;
}
因为这样编译器可以帮助你一点,但当然你还是要或多或少像使用 void * 一样小心.
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 *.
初始化...
你不必用任何东西标记缓冲区的结尾,因为结构中有一个大小变量.但如果你想这样做,我会让它自己的类型
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
然后对于 init 你可以这样做:
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;
虽然我倾向于使用head"来指代指向下一个要写入的位置的指针,但我不确定这有多标准.但是缓冲区是一个 strack_entries 数组,而不是 void *'s.
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.
这篇关于如何从堆栈中弹出不同类型的结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!