Compare commits

..
2 Commits
Author SHA1 Message Date
muckelbauerki98966 ed5f4eedc8 Final 2025-12-15 21:04:35 +01:00
muckelbauerki98966 d56c77d77a Fertig 2025-12-09 14:41:22 +01:00
45 changed files with 672 additions and 208 deletions

No files matched your search

-62
View File
@@ -1,62 +0,0 @@
# ---> C
# Prerequisites
*.d
# Object files
*.o
*.ko
*.obj
*.elf
# Linker output
*.ilk
*.map
*.exp
# Precompiled Headers
*.gch
*.pch
# Libraries
*.lib
*.la
*.lo
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex
Startcode/doble_initial
Startcode/doble
Startcode/unitTests
# Debug files
*.dSYM/
*.su
*.idb
*.pdb
# Kernel Module Compile Results
*.mod*
*.cmd
.tmp_versions/
modules.order
Module.symvers
Mkfile.old
dkms.conf
# IDE folders
.vscode/
.idea/
# macOS
.DS_Store
Binary file not shown.
-36
View File
@@ -1,36 +0,0 @@
#include <string.h>
#include "stack.h"
#include "bintree.h"
//TODO: binären Suchbaum implementieren
/* * `addToTree`: fügt ein neues Element in den Baum ein (rekursiv),
* `clearTree`: gibt den gesamten Baum frei (rekursiv),
* `treeSize`: zählt die Knoten im Baum (rekursiv),
* `nextTreeData`: Traversierung mit Hilfe des zuvor implementierten Stacks. */
// Adds a copy of data's pointer destination to the tree using compareFct for ordering. Accepts duplicates
// if isDuplicate is NULL, otherwise ignores duplicates and sets isDuplicate to 1 (or to 0 if a new entry is added).
TreeNode *addToTree(TreeNode *root, const void *data, size_t dataSize, CompareFctType compareFct, int *isDuplicate)
{
}
// Iterates over the tree given by root. Follows the usage of strtok. If tree is NULL, the next entry of the last tree given is returned in ordering direction.
// Use your implementation of a stack to organize the iterator. Push the root node and all left nodes first. On returning the next element,
// push the top node and push all its left nodes.
void *nextTreeData(TreeNode *root)
{
}
// Releases all memory resources (including data copies).
void clearTree(TreeNode *root)
{
}
// Returns the number of entries in the tree given by root.
unsigned int treeSize(const TreeNode *root)
{
}
-1
View File
@@ -1 +0,0 @@
player1;3999
-49
View File
@@ -1,49 +0,0 @@
CC = gcc
FLAGS = -g -Wall -lm
ifeq ($(OS),Windows_NT)
include makefile_windows.variables
else
UNAME = $(shell uname)
ifeq ($(UNAME),Linux)
include makefile_linux.variables
else
include makefile_mac.variables
endif
endif
raylibfolder = ./raylib
unityfolder = ./unity
# --------------------------
# Initiales Programm bauen (zum ausprobieren)
# --------------------------
doble_initial:
$(CC) -o doble_initial $(BINARIES)/libdoble_complete.a
# --------------------------
# Selbst implementiertes Programm bauen
# --------------------------
program_obj_files = stack.o bintree.o numbers.o timer.o highscore.o
doble : main.o $(program_obj_files)
$(CC) $(FLAGS) $^ -o doble
$(program_obj_files): %.o: %.c
$(CC) -c $(FLAGS) $^ -o $@
# --------------------------
# Unit Tests
# --------------------------
unitTests:
echo "needs to be implemented"
# --------------------------
# Clean
# --------------------------
clean:
ifeq ($(OS),Windows_NT)
del /f *.o doble
else
rm -f *.o doble
endif
-26
View File
@@ -1,26 +0,0 @@
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <string.h>
#include "numbers.h"
#include "bintree.h"
//TODO: getDuplicate und createNumbers implementieren
/* * * Erzeugen eines Arrays mit der vom Nutzer eingegebenen Anzahl an Zufallszahlen.
* Sicherstellen, dass beim Befüllen keine Duplikate entstehen.
* Duplizieren eines zufälligen Eintrags im Array.
* in `getDuplicate()`: Sortieren des Arrays und Erkennen der doppelten Zahl durch Vergleich benachbarter Elemente. */
// Returns len random numbers between 1 and 2x len in random order which are all different, except for two entries.
// Returns NULL on errors. Use your implementation of the binary search tree to check for possible duplicates while
// creating random numbers.
unsigned int *createNumbers(unsigned int len)
{
}
// Returns only the only number in numbers which is present twice. Returns zero on errors.
unsigned int getDuplicate(const unsigned int numbers[], unsigned int len)
{
}
-33
View File
@@ -1,33 +0,0 @@
#include <stdlib.h>
#include "stack.h"
//TODO: grundlegende Stackfunktionen implementieren:
/* * `push`: legt ein Element oben auf den Stack,
* `pop`: entfernt das oberste Element,
* `top`: liefert das oberste Element zurück,
* `clearStack`: gibt den gesamten Speicher frei. */
// Pushes data as pointer onto the stack.
StackNode *push(StackNode *stack, void *data)
{
}
// 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)
{
}
// Returns the data of the top element.
void *top(StackNode *stack)
{
}
// Clears stack and releases all memory.
void clearStack(StackNode *stack)
{
}
+159
View File
@@ -0,0 +1,159 @@
#include <string.h>
#include "stack.h"
#include "bintree.h"
// Fügt ein neues Element in den Binärbaum ein.
// - data wird kopiert (tiefe Kopie)
// - compareFct bestimmt die Sortierreihenfolge
// - Duplikate sind erlaubt, außer isDuplicate ist gesetzt
TreeNode *addToTree(TreeNode *root, const void *data, size_t dataSize,
CompareFctType compareFct, int *isDuplicate)
{
// Ungültige Parameter → Baum unverändert zurückgeben
if (data == NULL || compareFct == NULL)
return root;
// Fall: leerer Teilbaum → neuer Knoten wird erzeugt
if (root == NULL)
{
// Speicher für neuen Baumknoten reservieren
TreeNode *node = malloc(sizeof(TreeNode));
if (node == NULL)
return NULL;
// Speicher für die Nutzdaten reservieren
node->data = malloc(dataSize);
if (node->data == NULL)
{
free(node);
return NULL;
}
// Daten in den Knoten kopieren
memcpy(node->data, data, dataSize);
// Linke und rechte Kindzeiger initialisieren
node->left = NULL;
node->right = NULL;
// Kein Duplikat, da neuer Knoten
if (isDuplicate != NULL)
*isDuplicate = 0;
return node;
}
// Vergleich der neuen Daten mit den Daten im aktuellen Knoten
int cmp = compareFct(data, root->data);
if (cmp < 0)
{
// Neuer Wert ist kleiner → Rekursion im linken Teilbaum
root->left = addToTree(root->left, data, dataSize, compareFct, isDuplicate);
}
else if (cmp > 0)
{
// Neuer Wert ist größer → Rekursion im rechten Teilbaum
root->right = addToTree(root->right, data, dataSize, compareFct, isDuplicate);
}
else
{
// Gleicher Wert → Duplikat
if (isDuplicate != NULL)
{
// Duplikat melden, aber nicht einfügen
*isDuplicate = 1;
}
else
{
// Duplikate sind erlaubt → z.B. links einfügen
root->left = addToTree(root->left, data, dataSize, compareFct, NULL);
}
}
// Wurzel des (Teil-)Baumes zurückgeben
return root;
}
// Globaler interner Stack für die Baum-Traversierung
// Ermöglicht ein strtok-ähnliches Iterator-Verhalten
static StackNode *iterStack = NULL;
// Hilfsfunktion:
// Legt den Startknoten und alle seine linken Nachfolger auf den Stack
static void pushLeftPath(TreeNode *start)
{
// Solange noch ein Knoten existiert
while (start != NULL)
{
// Aktuellen Knoten auf den Stack legen
iterStack = push(iterStack, start);
// Zum linken Kind weitergehen
start = start->left;
}
}
// Gibt nacheinander die Daten des Baumes in sortierter Reihenfolge zurück.
// - Beim ersten Aufruf root ≠ NULL → neue Traversierung
// - Danach root == NULL → nächstes Element liefern
void *nextTreeData(TreeNode *root)
{
if (root != NULL)
{
// Neue Traversierung starten → alten Stack leeren
if (iterStack != NULL)
{
clearStack(iterStack);
iterStack = NULL;
}
// Wurzel und alle linken Knoten auf den Stack legen
pushLeftPath(root);
}
// Kein weiteres Element vorhanden
if (iterStack == NULL)
return NULL;
// Oberstes Stack-Element holen (nächster Baumknoten)
TreeNode *node = (TreeNode *)top(iterStack);
iterStack = pop(iterStack);
// Rechten Teilbaum dieses Knotens behandeln
// → dessen linker Pfad wird auf den Stack gelegt
if (node->right != NULL)
pushLeftPath(node->right);
// Daten des aktuellen Knotens zurückgeben
return node->data;
}
// Gibt den gesamten Speicher des Baumes frei (inkl. gespeicherter Daten)
void clearTree(TreeNode *root)
{
// Abbruchbedingung der Rekursion
if (root == NULL)
return;
// Zuerst linken Teilbaum freigeben
clearTree(root->left);
// Dann rechten Teilbaum freigeben
clearTree(root->right);
// Danach Daten und Knoten selbst freigeben
free(root->data);
free(root);
}
// Liefert die Anzahl aller Knoten im Baum
unsigned int treeSize(const TreeNode *root)
{
// Leerer Baum hat Größe 0
if (root == NULL)
return 0;
// 1 (aktueller Knoten) + Größe linker + Größe rechter Teilbaum
return 1u + treeSize(root->left) + treeSize(root->right);
}
View File
File renamed without changes.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
File renamed without changes.
File renamed without changes.
BIN
View File
Binary file not shown.
+4
View File
@@ -0,0 +1,4 @@
Kilian;9927
Kilian;9915
Kilian;4975
player1;3999
File renamed without changes.
File renamed without changes.
File renamed without changes.
View File
File renamed without changes.
BIN
View File
Binary file not shown.
+99
View File
@@ -0,0 +1,99 @@
CC = gcc
FLAGS = -g -Wall -lm
ifeq ($(OS),Windows_NT)
include makefile_windows.variables
else
UNAME = $(shell uname)
ifeq ($(UNAME),Linux)
include makefile_linux.variables
else
include makefile_mac.variables
endif
endif
raylibfolder = ./raylib
unityfolder = ./unity
# --------------------------
# Phony Targets
# --------------------------
.PHONY: all doble doble_initial unitTests test_stack test_numbers clean vorbereitungen prepare
# Standard-Target
all: doble
# --------------------------
# Initiales Programm bauen (zum Ausprobieren)
# --------------------------
doble_initial:
$(CC) -o doble_initial $(BINARIES)/libdoble_complete.a
# --------------------------
# Selbst implementiertes Programm bauen
# --------------------------
program_obj_files = stack.o bintree.o numbers.o timer.o highscore.o
doble: main.o $(program_obj_files)
$(CC) $(FLAGS) $^ -o doble
# Generische Regel zum Bauen von .o aus .c
%.o: %.c
$(CC) $(FLAGS) -c $< -o $@
# Abhängigkeiten (optional, aber hilfreich für inkrementelles Bauen)
main.o: main.c numbers.h stack.h bintree.h timer.h highscore.h
numbers.o: numbers.c numbers.h bintree.h
bintree.o: bintree.c bintree.h stack.h
stack.o: stack.c stack.h
timer.o: timer.c timer.h
highscore.o: highscore.c highscore.h
test_stack.o: test_stack.c stack.h
test_numbers.o: test_numbers.c numbers.h bintree.h stack.h
# --------------------------
# Unit Tests
# --------------------------
test_stack: test_stack.o stack.o
$(CC) $(FLAGS) $^ -o test_stack
test_numbers: test_numbers.o numbers.o stack.o bintree.o
$(CC) $(FLAGS) $^ -o test_numbers
unitTests: test_stack test_numbers
./test_stack
./test_numbers
# --------------------------
# Vorbereitungen zum Bauen des Programms
# --------------------------
vorbereitungen:
@echo "== Vorbereitungen zum Bauen des Programms =="
@echo "Prüfe benötigte Dateien..."
@test -f numbers.c || (echo "FEHLT: numbers.c" && exit 1)
@test -f numbers.h || (echo "FEHLT: numbers.h" && exit 1)
@test -f bintree.c || (echo "FEHLT: bintree.c" && exit 1)
@test -f bintree.h || (echo "FEHLT: bintree.h" && exit 1)
@test -f stack.c || (echo "FEHLT: stack.c" && exit 1)
@test -f stack.h || (echo "FEHLT: stack.h" && exit 1)
@test -f timer.c || (echo "FEHLT: timer.c" && exit 1)
@test -f timer.h || (echo "FEHLT: timer.h" && exit 1)
@test -f highscore.c || (echo "FEHLT: highscore.c" && exit 1)
@test -f highscore.h || (echo "FEHLT: highscore.h" && exit 1)
@test -f main.c || (echo "FEHLT: main.c" && exit 1)
@echo "Alle Dateien vorhanden."
@echo "Vorbereitung abgeschlossen!"
# englischer Alias
prepare: vorbereitungen
# --------------------------
# Clean
# --------------------------
clean:
ifeq ($(OS),Windows_NT)
del /f *.o doble doble_initial test_stack test_numbers
else
rm -f *.o doble doble_initial test_stack test_numbers
endif
File renamed without changes.
File renamed without changes.
File renamed without changes.
+113
View File
@@ -0,0 +1,113 @@
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <string.h>
#include "numbers.h"
#include "bintree.h"
// Hilfsfunktion für qsort und den Binärbaum: Vergleich von unsigned int
static int compareUnsignedInt(const void *a, const void *b)
{
const unsigned int *ua = (const unsigned int *)a;
const unsigned int *ub = (const unsigned int *)b;
if (*ua < *ub)
return -1;
else if (*ua > *ub)
return 1;
else
return 0;
}
// Returns len random numbers between 1 and 2x len in random order which are all different, except for two entries.
// Returns NULL on errors. Use your implementation of the binary search tree to check for possible duplicates while
// creating random numbers.
unsigned int *createNumbers(unsigned int len)
{
if (len < 2)
return NULL;
unsigned int *numbers = malloc(len * sizeof(unsigned int));
if (numbers == NULL)
return NULL;
// Zufall initialisieren
srand((unsigned int)time(NULL));
TreeNode *root = NULL;
unsigned int i = 0;
// len-1 verschiedene Zufallszahlen im Bereich [1, 2*len] erzeugen
while (i < len - 1)
{
unsigned int candidate = (unsigned int)(rand() % (2 * len)) + 1;
int isDuplicate = 0;
TreeNode *newRoot = addToTree(root, &candidate, sizeof(unsigned int),
compareUnsignedInt, &isDuplicate);
if (newRoot == NULL && root == NULL)
{
// Speicherfehler beim ersten Einfügen
clearTree(root);
free(numbers);
return NULL;
}
root = newRoot;
if (!isDuplicate)
{
numbers[i] = candidate;
++i;
}
// bei Duplikat wird einfach eine neue Zufallszahl generiert
}
// Einen zufälligen Eintrag aus den ersten len-1 duplizieren
unsigned int duplicateIndex = (unsigned int)(rand() % (len - 1));
numbers[len - 1] = numbers[duplicateIndex];
// Baum wird nicht mehr benötigt
clearTree(root);
// Das Array durchmischen (Fisher-Yates-Shuffle), damit das Duplikat an zufälliger Position steht
for (unsigned int j = len - 1; j > 0; --j)
{
unsigned int k = (unsigned int)(rand() % (j + 1));
unsigned int tmp = numbers[j];
numbers[j] = numbers[k];
numbers[k] = tmp;
}
return numbers;
}
// Returns only the only number in numbers which is present twice. Returns zero on errors.
unsigned int getDuplicate(const unsigned int numbers[], unsigned int len)
{
if (numbers == NULL || len < 2)
return 0;
// Kopie des Arrays anlegen, da qsort in-place sortiert
unsigned int *copy = malloc(len * sizeof(unsigned int));
if (copy == NULL)
return 0;
memcpy(copy, numbers, len * sizeof(unsigned int));
// Sortieren mit qsort
qsort(copy, len, sizeof(unsigned int), compareUnsignedInt);
// Benachbarte Elemente vergleichen, um das Duplikat zu finden
unsigned int duplicate = 0;
for (unsigned int i = 1; i < len; ++i)
{
if (copy[i] == copy[i - 1])
{
duplicate = copy[i];
break;
}
}
free(copy);
return duplicate; // 0 falls kein Duplikat gefunden (Fehlerfall)
}
View File
File renamed without changes.
BIN
View File
Binary file not shown.
+46
View File
@@ -0,0 +1,46 @@
#include <stdlib.h>
#include "stack.h"
// Pushes data as pointer onto the stack.
StackNode *push(StackNode *stack, void *data)
{
StackNode *node = (StackNode *)malloc(sizeof(StackNode));
if (node == NULL)
return stack; // keine Änderung bei Speicherfehler
node->data = data;
node->next = stack;
return node;
}
// 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 == NULL)
return NULL;
StackNode *next = stack->next;
free(stack);
return next;
}
// Returns the data of the top element.
void *top(StackNode *stack)
{
if (stack == NULL)
return NULL;
return stack->data;
}
// Clears stack and releases all memory.
void clearStack(StackNode *stack)
{
while (stack != NULL)
{
StackNode *next = stack->next;
free(stack);
stack = next;
}
}
+7 -1
View File
@@ -7,7 +7,12 @@ The latest element is taken from the stack. */
#include <stdlib.h>
//TODO: passenden Datentyp als struct anlegen
// einfacher verketteter Stack
typedef struct StackNode
{
void *data;
struct StackNode *next;
} StackNode;
// Pushes data as pointer onto the stack.
StackNode *push(StackNode *stack, void *data);
@@ -23,3 +28,4 @@ void *top(StackNode *stack);
void clearStack(StackNode *stack);
#endif
BIN
View File
Binary file not shown.
+142
View File
@@ -0,0 +1,142 @@
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "numbers.h"
/*
* Unit-Tests für createNumbers und getDuplicate:
* - createNumbers liefert ein gültiges Array
* - alle Zahlen liegen im Bereich [1, 2*len]
* - genau eine Zahl kommt doppelt vor
* - getDuplicate findet genau diese doppelte Zahl
* - Fehlerfälle (NULL-Pointer, zu kleine Länge)
*/
/*
* Prüft ein Zahlenarray auf Korrektheit:
* - Array darf nicht NULL sein
* - Wertebereich muss stimmen
* - genau eine Zahl darf doppelt vorkommen
*/
static void check_numbers_array(unsigned int *numbers, unsigned int len)
{
unsigned int maxValue = 2 * len; // Maximal erlaubter Zahlenwert
unsigned int *counts; // Array zum Zählen der Vorkommen
unsigned int i;
unsigned int duplicatesCount = 0; // Zähler für doppelte Werte
assert(numbers != NULL); // Sicherstellen, dass das Array existiert
// Speicher für Zähler-Array reservieren und mit 0 initialisieren
counts = (unsigned int *)calloc(maxValue + 1, sizeof(unsigned int));
assert(counts != NULL); // Prüfen, ob Speicher erfolgreich reserviert wurde
// Schleife über alle Elemente des numbers-Arrays
// Zählt die Werte und prüft gleichzeitig den gültigen Wertebereich
for (i = 0; i < len; ++i)
{
unsigned int v = numbers[i]; // Aktueller Wert
assert(v >= 1 && v <= maxValue); // Wertebereich prüfen
counts[v]++; // Anzahl dieses Wertes erhöhen
}
// Schleife über alle möglichen Werte
// Prüft, dass genau ein Wert doppelt vorkommt
for (i = 1; i <= maxValue; ++i)
{
if (counts[i] == 2)
duplicatesCount++; // Ein doppelter Wert gefunden
else
assert(counts[i] == 0 || counts[i] == 1); // Alle anderen max. einmal
}
assert(duplicatesCount == 1); // Es darf genau ein Duplikat geben
free(counts); // Speicher freigeben
}
/*
* Testet createNumbers und getDuplicate für eine gegebene Länge
*/
static void test_createNumbers_and_getDuplicate(unsigned int len)
{
printf("test_createNumbers_and_getDuplicate(len=%u)...\n", len);
// Zahlenarray erzeugen
unsigned int *numbers = createNumbers(len);
assert(numbers != NULL); // Rückgabewert prüfen
// Struktur und Inhalt des Arrays überprüfen
check_numbers_array(numbers, len);
// Erneutes Zählen, um das erwartete Duplikat zu ermitteln
unsigned int maxValue = 2 * len;
unsigned int *counts = (unsigned int *)calloc(maxValue + 1, sizeof(unsigned int));
assert(counts != NULL);
// Schleife zum Zählen aller Werte
for (unsigned int i = 0; i < len; ++i)
{
unsigned int v = numbers[i];
counts[v]++;
}
// Schleife zur Bestimmung des doppelten Wertes
unsigned int expectedDuplicate = 0;
for (unsigned int v = 1; v <= maxValue; ++v)
{
if (counts[v] == 2)
{
expectedDuplicate = v; // Doppelten Wert merken
break;
}
}
assert(expectedDuplicate != 0); // Es muss ein Duplikat existieren
// getDuplicate-Funktion testen
unsigned int found = getDuplicate(numbers, len);
assert(found == expectedDuplicate); // Ergebnis vergleichen
free(counts); // Speicher freigeben
free(numbers);
printf("...OK\n");
}
/*
* Testet Fehlerfälle für getDuplicate
*/
static void test_getDuplicate_error_cases(void)
{
printf("test_getDuplicate_error_cases...\n");
// Test mit NULL-Pointer
unsigned int dup = getDuplicate(NULL, 10);
assert(dup == 0);
// Test mit zu kleiner Länge (< 2)
unsigned int dummy[1] = {42};
dup = getDuplicate(dummy, 1);
assert(dup == 0);
printf("...OK\n");
}
/*
* Hauptfunktion: startet alle Unit-Tests
*/
int main(void)
{
printf("Running numbers unit tests...\n\n");
// Typische Testfälle mit unterschiedlichen Array-Längen
test_createNumbers_and_getDuplicate(5);
test_createNumbers_and_getDuplicate(10);
test_createNumbers_and_getDuplicate(20);
// Test der Fehlerfälle
test_getDuplicate_error_cases();
printf("\nAll numbers tests passed.\n");
return 0;
}
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+102
View File
@@ -0,0 +1,102 @@
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "stack.h"
/*
* Einfache Unit-Tests für den Stack:
* - push/pop: LIFO-Verhalten
* - top: richtiges Element
* - Verhalten bei leerem Stack
*/
static void test_push_pop_lifo(void)
{
printf("test_push_pop_lifo...\n");
StackNode *stack = NULL;
int a = 1;
int b = 2;
int c = 3;
stack = push(stack, &a);
stack = push(stack, &b);
stack = push(stack, &c);
// LIFO: zuerst c
assert(top(stack) == &c);
stack = pop(stack);
// dann b
assert(top(stack) == &b);
stack = pop(stack);
// dann a
assert(top(stack) == &a);
stack = pop(stack);
// jetzt leer
assert(stack == NULL);
assert(top(stack) == NULL);
printf("...OK\n");
}
static void test_empty_stack_operations(void)
{
printf("test_empty_stack_operations...\n");
StackNode *stack = NULL;
// pop auf leerem Stack sollte einfach NULL liefern
stack = pop(stack);
assert(stack == NULL);
// top auf leerem Stack sollte NULL liefern
assert(top(stack) == NULL);
// clearStack auf leerem Stack darf nicht crashen
clearStack(stack);
printf("...OK\n");
}
static void test_clearStack(void)
{
printf("test_clearStack...\n");
StackNode *stack = NULL;
int values[10];
int i;
// Wir legen 10 Elemente auf den Stack
for (i = 0; i < 10; ++i)
{
values[i] = i;
stack = push(stack, &values[i]);
}
// Stack leeren – clearStack muss alle StackNodes freigeben
clearStack(stack);
stack = NULL; // Pointer selbst auf NULL setzen
// Auf leerem Stack dürfen die Operationen nicht crashen
assert(top(stack) == NULL);
stack = pop(stack);
assert(stack == NULL);
printf("...OK\n");
}
int main(void)
{
printf("Running stack unit tests...\n\n");
test_push_pop_lifo();
test_empty_stack_operations();
test_clearStack();
printf("\nAll stack tests passed.\n");
return 0;
}
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
View File
File renamed without changes.
View File
File renamed without changes.
BIN
View File
Binary file not shown.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.