开发者

C Typed Stack: Linked-List Implementation

开发者 https://www.devze.com 2023-04-07 23:39 出处:网络
I have a computer science exam coming up and a large portion is going to be on programming in ansi C. I\'m new to C and as a review I tried to implement a stack using a linked-list. My code compiles b

I have a computer science exam coming up and a large portion is going to be on programming in ansi C. I'm new to C and as a review I tried to implement a stack using a linked-list. My code compiles but it doesn't run as expected.

I believe there is an error with my push() function. I'm assuming that my stack reference isn't being updated properly.

I wrote the following code from scratch to study / practice. Any advice on how to fix my code or improve my programming style would be greatly appreciated.

Thanks guys!


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(stac开发者_开发技巧k, 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;
}


Really you are not modifying stack. You must to use &stack for push, pop and empty methods. They will have following signature:

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

and, of course, use pointer contents inside these methods, like:

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

精彩评论

暂无评论...
验证码 换一张
取 消