我试图创建一个堆栈,我可以将整数推入其中。到目前为止,我有这个:
#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; //创建空堆栈
(可能没有创建空堆栈)
但我知道这是怎么回事
答案 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指针,您可以考虑将top
和size
都保留为字段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
调试器。