如何创建一个空堆栈?

时间:2016-11-18 03:07:01

标签: c stack

我试图创建一个堆栈,我可以将整数推入其中。到目前为止,我有这个:

#include <stdio.h>
#define N 20

typedef struct {
    int data[N]; // array of at most size N
    // N should be a constant declared globally
    int top;
} stack_t;

void push(stack_t *stack, int element);


int main(){

void push(stack_t *stack, int n) {
    if (stack->top == N - 1) {
        printf("Warning: Stack is full, You can't add'\n");
        return;
    } else {
        stack->data[++stack->top] = n;
    }
    }


    stack_t * e_stack; // Empty stack created
    push(e_stack, 2);


}

但是,此代码会产生运行时错误。我认为这是因为这部分是错误的:     stack_t * e_stack; //创建空堆栈

(可能没有创建空堆栈)

但我知道这是怎么回事

3 个答案:

答案 0 :(得分:1)

你是对的,你所做的就是创造一个指向某事物的指针,但可能不是stack_t。你需要分配一些东西来指出。见malloc。然后,您需要将stack_t::top初始化为-1或其他值。零可能在这里不起作用,因为该索引可能是堆栈中的第一个项目。

答案 1 :(得分:0)

这是我刚才写的一个例子。它基本上将整数推入堆栈,并将最近添加的项目弹出到堆栈。注意,弹出项目可能不是最好的方法,当然有更好的方法。

示例代码:

#include <stdio.h>
#include <stdlib.h>

#define N 20

typedef struct {
    int data[N]; //better to use a dynamic array instead here
    int top;
} stack_t;

stack_t *create_empty_stack(void);
void push(stack_t *stack, int value);
int pop(stack_t *stack); 

int 
main(void) {
    stack_t *stack;
    stack = create_empty_stack();

    push(stack, 10);
    push(stack, 20);
    push(stack, 30);

    printf("Popped: %d\n", pop(stack));
    printf("Popped: %d\n", pop(stack));
    printf("Popped: %d\n", pop(stack));
    printf("Popped: %d\n", pop(stack));

    free(stack);

    return 0;
}

void
push(stack_t *stack, int value) {
    if (stack->top == N - 1) {
        printf("Warning: Stack is full, You can't add'\n");
        return;
    } else {
        stack->data[stack->top] = value;
        (stack->top)++;
    }
}

int
pop(stack_t *stack) {
    if (stack->top > 0) {
        (stack->top)--;
        return stack->data[stack->top];
    } else {
        //definetly better way to do this. I will let you decided how you want to implement this.
        printf("Tried to pop empty stack!\n"); 
        exit(EXIT_FAILURE);
    }
}

// Since you are using a fixed sized array, creating an empty stack in this case is easy.
stack_t
*create_empty_stack(void) {
    stack_t *stack = malloc(sizeof(*stack));
    if (stack == NULL) {
        printf("Cannot allocate stack\n");
        exit(EXIT_FAILURE);
    }
    stack->top = 0;
    return stack;
}

答案 2 :(得分:0)

要么(如其他答案所示)分配一个内存区域并在堆上获得指向stack_t的指针并正确初始化它(可能通过create_empty_stack函数)或声明stack_t local variable(在call stack上),显式初始化它,并将指针传递给它:

 stack_t locstack = {.data={}, .top=0};
 push(&locstack, 2);  

BTW,正如Jonathan Leffler所评论,您的代码不是标准C99或C11,因为标准C中不允许nested functions。您(可能不正确)使用了一些GCC extension。您应该在push之外(和之前)定义main函数。如果您关心效率,请将其定义为static inline void push(stack_t *stack, int n) ....以获取效率inlined

请注意,如果你想接受任意大小的堆栈,可以考虑使用一些flexible array member,并根据需要增长它们(偶尔一次)(当堆栈满了时想一些int newsize = 4*stack->size/3+2;,然后stack_t*newstack = malloc(sizeof(stack_t)+newsize*sizeof(int));等......和使用heap allocated指针,您可以考虑将topsize都保留为字段stack_t的{​​{1}},data[]为{最后一个flexible array member。在这种情况下,push可能会返回一个(可能更新的)指针。

顺便说一句,只要你使用像malloc这样的堆分配,你总是应该处理失败,至少如下:

 stack_t* pstack = malloc(sizeof(stack_t)); 
 if (pstack==NULL) { perror("malloc"); exit(EXIT_FAILURE); };

(如果你有一些 如果使用GCC,请详细了解其command options(他们的订单很重要)。我建议使用gcc -std=c99 -Wall -Wextra -g进行编译(在原始代码中,应该提供一些有用的诊断),改进代码直到没有警告,然后使用gdb调试器。