2011-09-28 48 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