Implementierung Stack

This commit is contained in:
Alexander Schneider 2025-12-11 20:52:17 +01:00
parent 888b7f1c29
commit 5989d871ec
5 changed files with 137 additions and 15 deletions

View File

@ -1 +1,2 @@
Alex;14964
player1;3999

View File

@ -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
rm -f *.o *.exe doble $(TEST_STACK_EXEC)
endif
.PHONY: doble_initial doble unitTests $(TEST_STACK_EXEC) clean

41
stack.c
View File

@ -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;
}
// Deletes the top element of the stack (latest added element) and releases its memory. (Pointer to data has to be
// freed by caller.)
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.)
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;
}

View File

@ -8,6 +8,10 @@ The latest element is taken from the stack. */
#include <stdlib.h>
//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

67
test_stack.c Normal file
View File

@ -0,0 +1,67 @@
#include <stdlib.h>
#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();
}