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);
}
}
精彩评论