如何从堆栈中弹出不同类型的结构

时间:2014-03-29 14:20:52

标签: c struct stack

我有一个包含两种类型结构的堆栈。结构研究和结构教授 当我想推送一些东西时,我为两个结构创建了两个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;
}

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 *。