我有一个包含两种类型结构的堆栈。结构研究和结构教授 当我想推送一些东西时,我为两个结构创建了两个Push函数。虽然我希望它有一个功能但是我可以忍受它。
现在流行。如果我想从Stack中弹出一个学生,我是否必须专门为学生制作一个Pop功能?教授一样吗?
如果我不知道它是什么类型,我该如何存储该项目?元素必须是什么类型,才能将项目存储在那里?
以下是结构:
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功能。我在函数中传递了什么类型的项目?
int Pop(STACK *stack,int *head,??? *elem)
{
if(stack->head<=-1)
return 0;
*elem=stack->stack[*head];
*head--;
return 1;
}
答案 0 :(得分:1)
您必须在推送时对类型信息进行编码,最简单的可能是键入标记:
#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”更流畅的名字。另外,使用union会稍微好一点:
struct stack_entry {
int type;
union {
struct stud *stud;
struct prof *prof;
} item;
}
因为编译器可以帮助你一点点,但是当然你仍然需要或多或少地像使用void *那样小心。
编辑:初始化......
由于结构中有一个大小变量,因此您无需用任何内容标记缓冲区的结尾。但是如果你想这样做,我就会拥有自己的类型
#define END_OF_BUFFER 1
#define STUD 2
#define PROF 3
然后对于init你可以这样做:
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 *。