2011-09-28 123 views
-1

我有一個計算機科學考試即將到來,而且很大一部分將在ansi C編程。我是C新手,作爲一個複習,我嘗試使用堆棧實現堆棧一個鏈表。我的代碼編譯但它不按預期運行。C鍵入堆棧:鏈接列表實現

我相信我的push()函數有錯誤。我假設我的堆棧引用沒有被正確更新。

我寫了下面的代碼從頭開始學習/練習。任何關於如何修復我的代碼或改進我的編程風格的建議將不勝感激。

謝謝你們!


stack.h

#ifndef __STACK__ 
#define __STACK__ 

#include <stdlib.h> 
#include "bool.h" 

#define EMPTY -1 

typedef struct Node { 
    int index; 
    enum { INT = 0, CHAR, STRING } type; 
    union { 
     int i; 
     char c; 
     char* s; 
    } value; 
    struct Node* prev; 
} Node; 

typedef Node* Stack; 

Stack init(); 
void push(Stack stack, int type, void* value); 
void pop(Stack stack, Node* node); 
void empty(Stack stack); 
Bool isempty(Stack stack); 

#endif 

stack.c

#include <stdlib.h> 
#include <string.h> 
#include "stack.h" 

Stack init() { 
    Stack stack = (Node*) malloc(sizeof(Node)); 
    stack->index = EMPTY; 
    stack->type = INT; 
    stack->value.i = 0; 
    stack->prev = 0; 
    return stack; 
} 

void push(Stack stack, int type, void* value) { 
    int length; 
    Node* node = (Node*) malloc(sizeof(Node)); 
    node->index = stack->index + 1; 
    node->type = type; 
    switch(node->type) { 
     case INT: 
      node->value.i = *((int*) value); 
     break; 
     case CHAR: 
      node->value.c = *((char*) value); 
     break; 
     case STRING: 
      length = strlen((char*) value) + 1; 
      node->value.s = (char*) malloc(length * sizeof(char)); 
      strcpy(node->value.s, value); 
     break; 
    }  
    node->prev = stack; 
    stack = node; 
} 

void pop(Stack stack, Node* node) { 
    int length; 
    Node* temp = stack; 
    if (!isempty(stack)) { 
     node->index = stack->index; 
     node->type = stack->type; 
     switch(stack->type) { 
      case INT: 
       node->value.i = stack->value.i; 
      break; 
      case CHAR: 
       node->value.c = stack->value.c; 
      break; 
      case STRING: 
       length = strlen(stack->value.s) + 1; 
       node->value.s = (char*) malloc(length * sizeof(char)); 
       strcpy(node->value.s, stack->value.s); 
       free(stack->value.s); 
      break; 
     } 
     node->prev = 0; 
     stack = stack->prev; 
     free(temp); 
    } else { 
     /*TODO: handle empty case */  
     puts("Stack empty!"); 
    } 
} 

void empty(Stack stack) { 
    while (!isempty(stack)) { 
     Node* temp = malloc(sizeof(Node)); 
     pop(stack, temp); 
     free(temp); 
    } 
} 

Bool isempty(Stack stack) { 
    return stack->index == EMPTY ? TRUE : FALSE; 
} 

bool.h

#ifndef __BOOL__ 
#define __BOOL__ 

typedef int Bool; 

#define FALSE 0 
#define TRUE 1 

#endif 

的main.c

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

int main() { 
    Stack stack = init(); 
    Node* node = malloc(sizeof(Node)); 
    int i = 5; 
    push(stack, 0, &i); 
    pop(stack, node); 
    printf("Node value: %d\n", node->value.i); 
    free(node); 
    empty(stack); 
    puts("done."); 
    return 0; 
} 
+0

它不是爲了做功課的地方。更好地指出問題並針對具體問題尋求幫助。 – ManojGumber

+0

這不是作業。我希望得到任何明顯錯誤或可以改進的建議。 – Pooch

+3

你能詳細說明發生了什麼問題嗎? 另外一個更好的地方要問,這將是codereview.stackexchange.com –

回答

1

真的你不修改堆棧。您必須使用&堆棧來實現推送,彈出和空白方法。他們將有以下特徵:

void push(Stack * stack, int type, void* value); 
void pop(Stack * stack, Node* node); 
void empty(Stack *stack); 

,當然,使用指針內容這些方法裏面,比如:

void push(Stack * stack, int type, void* value) { 
    int length; 
    Node* node = (Node*) malloc(sizeof(Node)); 
    node->index = (*stack)->index + 1; 
    node->type = type; 
    switch(node->type) { 
     case INT: 
      node->value.i = *((int*) value); 
     break; 
     case CHAR: 
      node->value.c = *((char*) value); 
     break; 
     case STRING: 
      length = strlen((char*) value) + 1; 
      node->value.s = (char*) malloc(length * sizeof(char)); 
      strcpy(node->value.s, value); 
     break; 
    } 
    node->prev = *stack; 
    *stack = node; 
} 

void pop(Stack * stack, Node* node) { 
    int length; 
    Node* temp = *stack; 
    if (!isempty(*stack)) { 
     node->index = (*stack)->index; 
     node->type = (*stack)->type; 
     switch((*stack)->type) { 
      case INT: 
       node->value.i = (*stack)->value.i; 
      break; 
      case CHAR: 
       node->value.c = (*stack)->value.c; 
      break; 
      case STRING: 
       length = strlen((*stack)->value.s) + 1; 
       node->value.s = (char*) malloc(length * sizeof(char)); 
       strcpy(node->value.s, (*stack)->value.s); 
       free((*stack)->value.s); 
      break; 
     } 
     node->prev = 0; 
     *stack = (*stack)->prev; 
     free(temp); 
    } else { 
     /*TODO: handle empty case */ 
     puts("Stack empty!"); 
    } 
} 

void empty(Stack *stack) { 
    while (!isempty(*stack)) { 
     Node* temp = malloc(sizeof(Node)); 
     pop(stack, temp); 
     free(temp); 
    } 
} 
+0

感謝@ jcalvosa的迴應。你是對的,我是通過價值而不是通過引用通過堆棧。有點令人困惑的是,我需要一個指向指針的指針,並且認爲我可以通過棧來傳遞一個節點指針。欣賞建議! – Pooch