From 5989d871ec0954f9167dd8e5b39b4c3293184d74 Mon Sep 17 00:00:00 2001 From: schneideral98915 Date: Thu, 11 Dec 2025 20:52:17 +0100 Subject: [PATCH] Implementierung Stack --- highscores.txt | 1 + makefile | 36 ++++++++++++++++++--------- stack.c | 41 +++++++++++++++++++++++++++--- stack.h | 7 +++++- test_stack.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 137 insertions(+), 15 deletions(-) create mode 100644 test_stack.c diff --git a/highscores.txt b/highscores.txt index 4edd5a7..87f24c7 100644 --- a/highscores.txt +++ b/highscores.txt @@ -1 +1,2 @@ +Alex;14964 player1;3999 diff --git a/makefile b/makefile index 1f15f75..a4fc9c3 100644 --- a/makefile +++ b/makefile @@ -1,5 +1,5 @@ CC = gcc -FLAGS = -g -Wall -lm +CFLAGS = -g -Wall -lm ifeq ($(OS),Windows_NT) include makefile_windows.variables @@ -24,26 +24,40 @@ doble_initial: # -------------------------- # Selbst implementiertes Programm bauen # -------------------------- -program_obj_files = stack.o bintree.o numbers.o timer.o highscore.o +program_obj_files = main.o stack.o bintree.o numbers.o timer.o highscore.o -doble : main.o $(program_obj_files) - $(CC) $(FLAGS) $^ -o doble +doble : $(program_obj_files) + $(CC) $(CFLAGS) $^ -o doble -$(program_obj_filesobj_files): %.o: %.c - $(CC) -c $(FLAGS) $^ -o $@ # -------------------------- # Unit Tests # -------------------------- -unitTests: - echo "needs to be implemented" +TEST_STACK_EXEC = runtest_stack.exe + +unitTests: $(TEST_STACK_EXEC) + @echo "--- Starte Stack Unit Tests ---" + @echo "Versuche auszuführen: $(TEST_STACK_EXEC)" + $(TEST_STACK_EXEC) + @echo "--- Stack Unit Tests abgeschlossen ---" + +$(TEST_STACK_EXEC): test_stack.o stack.o + $(CC) $(CFLAGS) -I$(unityfolder) test_stack.o stack.o $(unityfolder)/unity.c -o $@ $(BINARIES)/libdoble_complete.a + +test_stack.o: test_stack.c + $(CC) -c $(CFLAGS) -I$(unityfolder) $< -o $@ + +%.o: %.c + $(CC) -c $(CFLAGS) $< -o $@ # -------------------------- # Clean # -------------------------- clean: ifeq ($(OS),Windows_NT) - del /f *.o doble + del /f *.o *.exe doble $(TEST_STACK_EXEC) else - rm -f *.o doble -endif \ No newline at end of file + rm -f *.o *.exe doble $(TEST_STACK_EXEC) +endif + +.PHONY: doble_initial doble unitTests $(TEST_STACK_EXEC) clean \ No newline at end of file diff --git a/stack.c b/stack.c index e3a90d4..2f1917d 100644 --- a/stack.c +++ b/stack.c @@ -10,24 +10,59 @@ // Pushes data as pointer onto the stack. StackNode *push(StackNode *stack, void *data) { + StackNode *newNode = (StackNode *)malloc(sizeof(StackNode)); + if(!newNode) { + return NULL; + } + + newNode->data = data; + + newNode->next = stack; + + return newNode; } -// Deletes the top element of the stack (latest added element) and releases its memory. (Pointer to data has to be -// freed by caller.) +// Deletes the top element of the stack (latest added element) and releases its memory. +// (Pointer to data has to be freed by caller.) StackNode *pop(StackNode *stack) { + if(!stack) { + return NULL; + } + StackNode *topNode = stack; + + stack = stack->next; + + free(topNode); + + return stack; } // Returns the data of the top element. void *top(StackNode *stack) { + if(!stack){ + return NULL; + } + + return stack->data; } // Clears stack and releases all memory. -void clearStack(StackNode *stack) +StackNode *clearStack(StackNode *stack) { + StackNode *current = stack; + StackNode *next_node; + + while(current){ + next_node = current->next; + free(current); + current = next_node; + } + + return NULL; } \ No newline at end of file diff --git a/stack.h b/stack.h index f7d542d..35c4933 100644 --- a/stack.h +++ b/stack.h @@ -8,6 +8,10 @@ The latest element is taken from the stack. */ #include //TODO: passenden Datentyp als struct anlegen +typedef struct StackNode { + void *data; + struct StackNode *next; +}StackNode; // Pushes data as pointer onto the stack. StackNode *push(StackNode *stack, void *data); @@ -20,6 +24,7 @@ StackNode *pop(StackNode *stack); void *top(StackNode *stack); // Clears stack and releases all memory. -void clearStack(StackNode *stack); +StackNode *clearStack(StackNode *stack); #endif + diff --git a/test_stack.c b/test_stack.c new file mode 100644 index 0000000..36fe949 --- /dev/null +++ b/test_stack.c @@ -0,0 +1,67 @@ +#include +#include "unity/unity.h" +#include "stack.h" + +void setUp(void) {} +void tearDown(void) {} + +static StackNode *stack = NULL; // Für gemeinsame Benutzung in Tests + +void test_push_and_top_should_return_last_integer(void) { + int *v1 = malloc(sizeof(int)); + int *v2 = malloc(sizeof(int)); + int *v3 = malloc(sizeof(int)); + *v1 = 12; *v2 = 34; *v3 = 56; + + // Push Werte auf Stack + stack = push(stack, v1); + TEST_ASSERT_NOT_NULL(stack); + TEST_ASSERT_EQUAL_INT(12, *(int *)top(stack)); + + stack = push(stack, v2); + TEST_ASSERT_EQUAL_INT(34, *(int *)top(stack)); + + stack = push(stack, v3); + TEST_ASSERT_EQUAL_INT(56, *(int *)top(stack)); + + // Ressourcen werden in anderem Test wieder entfernt! +} + +void test_pop_should_remove_and_free_integers(void) { + // Gibt die gleichen Werte wie im vorherigen Push-Test frei + int *val; + + val = top(stack); + TEST_ASSERT_EQUAL_INT(56, *val); + free(val); + stack = pop(stack); + + val = top(stack); + TEST_ASSERT_EQUAL_INT(34, *val); + free(val); + stack = pop(stack); + + val = top(stack); + TEST_ASSERT_EQUAL_INT(12, *val); + free(val); + stack = pop(stack); + + TEST_ASSERT_NULL(stack); +} + +void test_stack_empty_behavior(void) { + // Nach allen pops/clear-Operationen sollte Stack NULL sein + TEST_ASSERT_NULL(top(stack)); + StackNode *tmp = pop(stack); + TEST_ASSERT_NULL(tmp); + stack = clearStack(stack); // Sollte NULL bleiben + TEST_ASSERT_NULL(stack); +} + +int main(void) { + UNITY_BEGIN(); + RUN_TEST(test_push_and_top_should_return_last_integer); + RUN_TEST(test_pop_should_remove_and_free_integers); + RUN_TEST(test_stack_empty_behavior); + return UNITY_END(); +} \ No newline at end of file