2016-11-18 66 views
0

我想創建一個堆棧,我可以將整數推入它。到目前爲止,我有這樣的:如何創建一個空棧?

#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;創建//空棧

(這可能沒有創建一個空棧)

但我知道它是如何錯誤

+2

什麼是嵌套函數thingy?你應該在'main()'之外定義'push()'函數。只有在flaccid模式下的GCC允許嵌套函數 - 它們不可移植且通常是邪惡的,如果您正在學習C,則不應該使用它們(並且即使在您學習C之後也可能不會使用它們)。 –

回答

1

你說得對,你所做的一切是創建一個指針指向......某事,但可能不是stack_t。你需要分配一些東西來指出。見malloc。然後,您需要將stack_t::top初始化爲-1或其他值。零可能不會在這裏工作,因爲該索引可能是堆棧中的第一項。

+1

堆棧指針應該是下一個要使用的條目;它應該超過值0(空)到N(沒有剩餘空間)。它還指示堆棧中有多少條目。 –

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; 
} 
0

要麼(如其他答案建議)分配一個存儲區,並得到一個指針stack_t在堆上並正確初始化(也許通一個create_empty_stack功能)或聲明stack_tlocal variable (上call stack),明確初始化,然後將指針傳遞給它:

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

BTW,如Jonathan Leffler評論,你的代碼不是標準C99或C11,因爲標準C中不允許使用nested functions。您(可能是不正確)使用某些GCC extension。您應該在(以及之前)main之外定義push函數。如果您關心效率,請將其定義爲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的字段並將其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調試器。