Compare commits

..

No commits in common. "RMax" and "main" have entirely different histories.
RMax ... main

19 changed files with 236 additions and 966 deletions

5
.gitignore vendored
View File

@ -1,4 +1 @@
doble_initial.exe highscores.txt
*.o
*.exe
highscore.txt

View File

@ -1,18 +0,0 @@
{
"configurations": [
{
"name": "windows-gcc-x64",
"includePath": [
"${workspaceFolder}/**"
],
"compilerPath": "C:/ProgramData/mingw64/mingw64/bin/gcc.exe",
"cStandard": "${default}",
"cppStandard": "${default}",
"intelliSenseMode": "windows-gcc-x64",
"compilerArgs": [
""
]
}
],
"version": 4
}

24
.vscode/launch.json vendored
View File

@ -1,24 +0,0 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "C/C++ Runner: Debug Session",
"type": "cppdbg",
"request": "launch",
"args": [],
"stopAtEntry": false,
"externalConsole": true,
"cwd": "c:/Users/Max-R/I2Pr/info2Praktikum-DobleSpiel",
"program": "c:/Users/Max-R/I2Pr/info2Praktikum-DobleSpiel/build/Debug/outDebug",
"MIMode": "gdb",
"miDebuggerPath": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
}
]
}

59
.vscode/settings.json vendored
View File

@ -1,59 +0,0 @@
{
"C_Cpp_Runner.cCompilerPath": "gcc",
"C_Cpp_Runner.cppCompilerPath": "g++",
"C_Cpp_Runner.debuggerPath": "gdb",
"C_Cpp_Runner.cStandard": "",
"C_Cpp_Runner.cppStandard": "",
"C_Cpp_Runner.msvcBatchPath": "C:/Program Files/Microsoft Visual Studio/VR_NR/Community/VC/Auxiliary/Build/vcvarsall.bat",
"C_Cpp_Runner.useMsvc": false,
"C_Cpp_Runner.warnings": [
"-Wall",
"-Wextra",
"-Wpedantic",
"-Wshadow",
"-Wformat=2",
"-Wcast-align",
"-Wconversion",
"-Wsign-conversion",
"-Wnull-dereference"
],
"C_Cpp_Runner.msvcWarnings": [
"/W4",
"/permissive-",
"/w14242",
"/w14287",
"/w14296",
"/w14311",
"/w14826",
"/w44062",
"/w44242",
"/w14905",
"/w14906",
"/w14263",
"/w44265",
"/w14928"
],
"C_Cpp_Runner.enableWarnings": true,
"C_Cpp_Runner.warningsAsError": false,
"C_Cpp_Runner.compilerArgs": [],
"C_Cpp_Runner.linkerArgs": [],
"C_Cpp_Runner.includePaths": [],
"C_Cpp_Runner.includeSearch": [
"*",
"**/*"
],
"C_Cpp_Runner.excludeSearch": [
"**/build",
"**/build/**",
"**/.*",
"**/.*/**",
"**/.vscode",
"**/.vscode/**"
],
"C_Cpp_Runner.useAddressSanitizer": false,
"C_Cpp_Runner.useUndefinedSanitizer": false,
"C_Cpp_Runner.useLeakSanitizer": false,
"C_Cpp_Runner.showCompilationTime": false,
"C_Cpp_Runner.useLinkTimeOptimization": false,
"C_Cpp_Runner.msvcSecureNoWarnings": false
}

134
bintree.c
View File

@ -1,132 +1,36 @@
#include "bintree.h"
#include "stack.h"
#include <string.h> #include <string.h>
#include "stack.h"
#include "bintree.h"
// TODO: binären Suchbaum implementieren //TODO: binären Suchbaum implementieren
/* * `addToTree`: fügt ein neues Element in den Baum ein (rekursiv), /* * `addToTree`: fügt ein neues Element in den Baum ein (rekursiv),
* `clearTree`: gibt den gesamten Baum frei (rekursiv), * `clearTree`: gibt den gesamten Baum frei (rekursiv),
* `treeSize`: zählt die Knoten im Baum (rekursiv), * `treeSize`: zählt die Knoten im Baum (rekursiv),
* `nextTreeData`: Traversierung mit Hilfe des zuvor implementierten Stacks. */ * `nextTreeData`: Traversierung mit Hilfe des zuvor implementierten Stacks. */
// typedef int (*CompareFctType)(const void *arg1, const void *arg2); // Adds a copy of data's pointer destination to the tree using compareFct for ordering. Accepts duplicates
// Adds a copy of data's pointer destination to the tree using compareFct for // if isDuplicate is NULL, otherwise ignores duplicates and sets isDuplicate to 1 (or to 0 if a new entry is added).
// ordering. Accepts duplicates if isDuplicate is NULL, otherwise ignores TreeNode *addToTree(TreeNode *root, const void *data, size_t dataSize, CompareFctType compareFct, int *isDuplicate)
// duplicates and sets isDuplicate to 1 (or to 0 if a new entry is added). {
TreeNode *createTreeNode(const void *data, size_t dataSize) {
TreeNode *node =
malloc(sizeof(TreeNode)); // Speicher für neuen Knoten reservieren
if (node == NULL)
return NULL; // Abbrechen bei Fehler
node->data = malloc(dataSize); // Speicher für Daten reservieren
if (node->data == NULL) {
free(node);
return NULL;
}
memcpy(node->data, data, dataSize); // Standardfunktion string.h, kopiert
// size bytes von data nach node->data,
// daten dürfen sich nicht überschneiden
// speichern der Daten in node->data
node->left = NULL; // Kinder sind NULL
node->right = NULL;
return node;
} }
TreeNode *addToTree(TreeNode *root, const void *data, size_t dataSize, // 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.
CompareFctType compareFct, int *isDuplicate) { // 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)
{
// isDuplicate initialisieren (auf 0 setzen), verhindert Änderung am Baum
if (isDuplicate) {
*isDuplicate = 0;
} // bei 0: neuer Wert wurde eingefügt, bei 1: Wert war bereits im Baum
// leerer Baum
if (root == NULL) {
return createTreeNode(data, dataSize);
}
// mit compareFct <0 links >0 rechts =0 Duplikat
int compare = compareFct(data, root->data);
if (compare < 0) { // Eintrag links
root->left = addToTree(root->left, data, dataSize, compareFct, isDuplicate);
} else if (compare > 0) { // Eintrag rechts
root->right =
addToTree(root->right, data, dataSize, compareFct, isDuplicate);
} else { // Duplikat
// isDuplicate auf 1 setzen, keine Änderung am Baum
if (isDuplicate) {
*isDuplicate = 1;
}
}
return root;
}
// 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) {
static StackNode *stack = NULL; // static -> behält Wert bei mehreren Aufrufen
// Neue Iteration starten
if (root != NULL) {
clearStack(&stack); // alte Stack-Inhalte werden gelöscht
TreeNode *currentNode = root;
while (currentNode !=
NULL) { // alle linken Knoten werden vom root an auf den Stack gelegt
StackNode *oldStack = stack;
StackNode *newStack = push(stack, currentNode);
if (newStack == oldStack)
return NULL; // push fehlgeschlagen
stack = newStack;
currentNode = currentNode->left;
}
}
if (stack == NULL)
return NULL; // wenn Stack leer ist sind keine Elemente mehr vorhanden,
// Iteration beendet
// oberster Knoten vom Stack
TreeNode *node = top(stack);
stack = pop(stack);
// Rechten Teilbaum pushen
TreeNode *currentNode = node->right;
while (currentNode != NULL) {
StackNode *oldStack = stack;
StackNode *newStack = push(stack, currentNode);
if (newStack == oldStack)
return NULL; // push fehlgeschlagen
stack = newStack;
currentNode = currentNode->left;
}
return node->data; // Pointer auf Daten
} }
// Releases all memory resources (including data copies). // Releases all memory resources (including data copies).
void clearTree(TreeNode **root) { // rekursive Funktion zum freigeben des void clearTree(TreeNode *root)
// Speichers und Nullsetzen der Pointer {
if (root == NULL || *root == NULL)
return;
clearTree(&(*root)->left); // linken Teilbaum löschen
clearTree(&(*root)->right); // rechten Teilbaum löschen
free((*root)->data); // Daten freigeben
(*root)->data = NULL;
free(*root); // Knoten freigeben
*root = NULL; // Zeiger auf NULL setzen
} }
// Returns the number of entries in the tree given by root. // Returns the number of entries in the tree given by root.
unsigned int treeSize(const TreeNode *root) { unsigned int treeSize(const TreeNode *root)
{
if (root == NULL)
return 0;
return 1 + treeSize(root->left) + treeSize(root->right);
} }

View File

@ -5,27 +5,22 @@
typedef int (*CompareFctType)(const void *arg1, const void *arg2); typedef int (*CompareFctType)(const void *arg1, const void *arg2);
typedef struct node { typedef struct node
void *data; {
struct node *left; void *data;
struct node *right; struct node *left;
struct node *right;
} TreeNode; } TreeNode;
TreeNode *createTreeNode(const void *data, size_t dataSize); // 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).
// Adds a copy of data's pointer destination to the tree using compareFct for TreeNode *addToTree(TreeNode *root, const void *data, size_t dataSize, CompareFctType compareFct, int *isDuplicate);
// ordering. Accepts duplicates if isDuplicate is NULL, otherwise ignores // 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.
// duplicates and sets isDuplicate to 1 (or to 0 if a new entry is added). // Use your implementation of a stack to organize the iterator. Push the root node and all left nodes first. On returning the next element,
TreeNode *addToTree(TreeNode *root, const void *data, size_t dataSize, // push the top node and push all its left nodes.
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); void *nextTreeData(TreeNode *root);
// Releases all memory resources (including data copies). // Releases all memory resources (including data copies).
void clearTree(TreeNode **root); void clearTree(TreeNode *root);
// Returns the number of entries in the tree given by root. // Returns the number of entries in the tree given by root.
unsigned int treeSize(const TreeNode *root); unsigned int treeSize(const TreeNode *root);

Binary file not shown.

View File

@ -1,129 +1,134 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "highscore.h" #include "highscore.h"
#include "bintree.h" #include "bintree.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LINE_LEN 100 #define MAX_LINE_LEN 100
#define MAX_PLAYER_NAME_LEN 20 #define MAX_PLAYER_NAME_LEN 20
typedef struct { typedef struct
char name[MAX_PLAYER_NAME_LEN]; {
int score; char name[MAX_PLAYER_NAME_LEN];
int score;
} HighscoreEntry; } HighscoreEntry;
static TreeNode *highscoreTree = NULL; static TreeNode *highscoreTree = NULL;
// Compare two highscore entries by score (descending), then by name // Compare two highscore entries by score (descending), then by name (ascending).
// (ascending). static int compareHighscoreEntries(const void *arg1, const void *arg2)
static int compareHighscoreEntries(const void *arg1, const void *arg2) { {
const HighscoreEntry *entry1 = (const HighscoreEntry *)arg1; const HighscoreEntry *entry1 = (const HighscoreEntry *)arg1;
const HighscoreEntry *entry2 = (const HighscoreEntry *)arg2; const HighscoreEntry *entry2 = (const HighscoreEntry *)arg2;
int result = entry2->score - entry1->score; int result = entry2->score - entry1->score;
if (result == 0) if(result == 0)
result = strcmp(entry1->name, entry2->name); result = strcmp(entry1->name, entry2->name);
return result; return result;
} }
// Create a new highscore entry from name and score. // Create a new highscore entry from name and score.
static HighscoreEntry createHighscoreEntry(const char *name, int score) { static HighscoreEntry createHighscoreEntry(const char *name, int score)
HighscoreEntry entry = {"", score}; {
HighscoreEntry entry = {"", score};
if (name != NULL) { if(name != NULL)
strncpy(entry.name, name, MAX_PLAYER_NAME_LEN); {
entry.name[MAX_PLAYER_NAME_LEN - 1] = '\0'; strncpy(entry.name, name, MAX_PLAYER_NAME_LEN);
} entry.name[MAX_PLAYER_NAME_LEN-1] = '\0';
}
return entry; return entry;
} }
// Calculate score based on time used and number of shown numbers. // Calculate score based on time used and number of shown numbers.
static int calculateScore(double timeInSeconds, unsigned int len) { static int calculateScore(double timeInSeconds, unsigned int len)
return (1000.0 - timeInSeconds) * len; {
return (1000.0 - timeInSeconds) * len;
} }
// Load highscores from file into memory. // Load highscores from file into memory.
void loadHighscores(const char *path) { void loadHighscores(const char *path)
FILE *file = fopen(path, "r"); {
FILE *file = fopen(path, "r");
if (file != NULL) { if(file != NULL)
char buffer[MAX_LINE_LEN + 1]; {
char buffer[MAX_LINE_LEN+1];
while (fgets(buffer, MAX_LINE_LEN + 1, file) != NULL) { while(fgets(buffer, MAX_LINE_LEN+1, file) != NULL)
char *name = strtok(buffer, ";\n"); {
char *scoreStr = strtok(NULL, ";\n"); char *name = strtok(buffer, ";\n");
char *scoreStr = strtok(NULL, ";\n");
if (name != NULL && scoreStr != NULL) { if(name != NULL && scoreStr != NULL)
HighscoreEntry entry = {
createHighscoreEntry(name, strtol(scoreStr, NULL, 10)); HighscoreEntry entry = createHighscoreEntry(name, strtol(scoreStr, NULL, 10));
highscoreTree = addToTree(highscoreTree, &entry, sizeof(entry), highscoreTree = addToTree(highscoreTree, &entry, sizeof(entry), compareHighscoreEntries, NULL);
compareHighscoreEntries, NULL); }
} }
fclose(file);
} }
fclose(file);
}
} }
// Add a new highscore entry and return the calculated score. // Add a new highscore entry and return the calculated score.
int addHighscore(const char *name, double timeInSeconds, unsigned int len) { int addHighscore(const char *name, double timeInSeconds, unsigned int len)
HighscoreEntry entry = {
createHighscoreEntry(name, calculateScore(timeInSeconds, len)); HighscoreEntry entry = createHighscoreEntry(name, calculateScore(timeInSeconds, len));
highscoreTree = addToTree(highscoreTree, &entry, sizeof(entry), highscoreTree = addToTree(highscoreTree, &entry, sizeof(entry), compareHighscoreEntries, NULL);
compareHighscoreEntries, NULL);
return entry.score; return entry.score;
} }
// Print highscores (up to NUMBER_OF_SHOWN_HIGHSCORES) in a formatted table. // Print highscores (up to NUMBER_OF_SHOWN_HIGHSCORES) in a formatted table.
void showHighscores() { void showHighscores()
const char *blanks = {
" " const char *blanks = " ";
" "; const char *stripes = "------------------------------------------------------------------------------------------------------------------------";
const char *stripes = const char *header = "H I G H S C O R E S";
"------------------------------------------------------------------------" const int lineWidth = MAX_PLAYER_NAME_LEN + MAX_PLAYER_NAME_LEN + 5;
"------------------------------------------------";
const char *header = "H I G H S C O R E S";
const int lineWidth = MAX_PLAYER_NAME_LEN + MAX_PLAYER_NAME_LEN + 5;
int blankSpace = (int)(lineWidth - strlen(header)) / 2; int blankSpace = (int)(lineWidth - strlen(header)) / 2;
HighscoreEntry *entry = nextTreeData(highscoreTree); HighscoreEntry *entry = nextTreeData(highscoreTree);
printf("+%*.*s+\n", lineWidth, lineWidth, stripes);
printf("|%*.*s%s%*.*s|\n", blankSpace, blankSpace, blanks, header, blankSpace,
blankSpace, blanks);
printf("+%*.*s+\n", lineWidth, lineWidth, stripes);
for (int i = 0; i < NUMBER_OF_SHOWN_HIGHSCORES && entry != NULL; i++) {
printf("| %-*s | %*d |\n", MAX_PLAYER_NAME_LEN, entry->name,
MAX_PLAYER_NAME_LEN, entry->score);
printf("+%*.*s+\n", lineWidth, lineWidth, stripes); printf("+%*.*s+\n", lineWidth, lineWidth, stripes);
entry = nextTreeData(NULL); printf("|%*.*s%s%*.*s|\n", blankSpace, blankSpace, blanks, header, blankSpace, blankSpace, blanks);
} printf("+%*.*s+\n", lineWidth, lineWidth, stripes);
for(int i = 0; i < NUMBER_OF_SHOWN_HIGHSCORES && entry != NULL; i++)
{
printf("| %-*s | %*d |\n", MAX_PLAYER_NAME_LEN, entry->name, MAX_PLAYER_NAME_LEN, entry->score);
printf("+%*.*s+\n", lineWidth, lineWidth, stripes);
entry = nextTreeData(NULL);
}
} }
// Save highscores to file (up to NUMBER_OF_SHOWN_HIGHSCORES). // Save highscores to file (up to NUMBER_OF_SHOWN_HIGHSCORES).
void saveHighscores(const char *path) { void saveHighscores(const char *path)
FILE *file = fopen(path, "w"); {
FILE *file = fopen(path, "w");
if (file != NULL) { if(file != NULL)
HighscoreEntry *entry = nextTreeData(highscoreTree); {
HighscoreEntry *entry = nextTreeData(highscoreTree);
for (int i = 0; i < NUMBER_OF_SHOWN_HIGHSCORES && entry != NULL; i++) { for(int i = 0; i < NUMBER_OF_SHOWN_HIGHSCORES && entry != NULL; i++)
fprintf(file, "%s;%d\n", entry->name, entry->score); {
entry = nextTreeData(NULL); fprintf(file, "%s;%d\n", entry->name, entry->score);
entry = nextTreeData(NULL);
}
fclose(file);
} }
fclose(file);
}
} }
// Free all memory used for highscores. // Free all memory used for highscores.
void clearHighscores() { void clearHighscores()
clearTree(&highscoreTree); {
highscoreTree = NULL; clearTree(highscoreTree);
highscoreTree = NULL;
} }

View File

@ -1,10 +1 @@
max20;19879 player1;3999
max10;9970
max;9965
Kristin;9944
Kristin;7947
Kristin;6962
Kristin;5987
Kristin;5975
krisp;4986
krisp;4985

132
main.c
View File

@ -1,88 +1,90 @@
#include "highscore.h" #include <stdlib.h>
#include <stdio.h>
#include "numbers.h" #include "numbers.h"
#include "timer.h" #include "timer.h"
#include <stdio.h> #include "highscore.h"
#include <stdlib.h>
#include <time.h>
// Read an unsigned integer from stdin with prompt (retries until valid). // Read an unsigned integer from stdin with prompt (retries until valid).
int inputNumber(const char *promptText) { int inputNumber(const char *promptText)
unsigned int number; {
int numberOfInputs = 0; unsigned int number;
int numberOfInputs = 0;
while (numberOfInputs != 1) { while(numberOfInputs != 1)
printf("%s", promptText); {
numberOfInputs = scanf("%u", &number); printf("%s", promptText);
while (getchar() != '\n') { numberOfInputs = scanf("%u", &number);
} // clear input buffer while(getchar() != '\n') {} // clear input buffer
} }
return number; return number;
} }
// Print an array of numbers. // Print an array of numbers.
void showNumbers(const unsigned int *numbers, unsigned int len) { void showNumbers(const unsigned int *numbers, unsigned int len)
if (numbers != NULL) { {
printf("Numbers:"); if(numbers != NULL)
{
printf("Numbers:");
for (int i = 0; i < len; i++) for(int i = 0; i < len; i++)
printf(" %5d", numbers[i]); printf(" %5d", numbers[i]);
printf("\n"); printf("\n");
} }
} }
// Main game loop: generate numbers, ask user for duplicate, measure time, // Main game loop: generate numbers, ask user for duplicate, measure time, update highscores.
// update highscores. int main(int argc, char *argv[])
int main(int argc, char *argv[]) { {
srand(time(NULL)); // seed für srand int exitCode = EXIT_FAILURE;
int exitCode = EXIT_FAILURE;
if (argc != 2) { if(argc != 2)
fprintf(stderr, "Usage: %s <player name>\n", argv[0]); {
exitCode = EXIT_FAILURE; fprintf(stderr, "Usage: %s <player name>\n", argv[0]);
} else { exitCode = EXIT_FAILURE;
const char *highscorePath = "highscores.txt"; }
const char *playerName = argv[1]; else
unsigned int *numbers = NULL; {
unsigned int duplicate = 0; const char *highscorePath = "highscores.txt";
double measuredSeconds; const char *playerName = argv[1];
unsigned int userInput; unsigned int *numbers = NULL;
unsigned int numberOfElements = 0; unsigned int duplicate = 0;
double measuredSeconds;
unsigned int userInput;
unsigned int numberOfElements = 0;
// ask until valid number of elements (3..1000) // ask until valid number of elements (3..1000)
while (numberOfElements < 3 || numberOfElements > 1000) while(numberOfElements < 3 || numberOfElements > 1000)
numberOfElements = numberOfElements = inputNumber("Wie viele Zahlen sollen gezeigt werden: ");
inputNumber("Wie viele Zahlen sollen gezeigt werden: ");
// create numbers and show them // create numbers and show them
numbers = createNumbers(numberOfElements); numbers = createNumbers(numberOfElements);
showNumbers(numbers, numberOfElements); showNumbers(numbers, numberOfElements);
// measure time while user guesses the duplicate // measure time while user guesses the duplicate
startTimer(); startTimer();
userInput = inputNumber("Welche Zahl kommt doppelt vor: "); userInput = inputNumber("Welche Zahl kommt doppelt vor: ");
measuredSeconds = stopTimer(); measuredSeconds = stopTimer();
duplicate = getDuplicate(numbers, numberOfElements); duplicate = getDuplicate(numbers, numberOfElements);
// check result and update highscores // check result and update highscores
if (userInput == duplicate) { if(userInput == duplicate)
int score = addHighscore(playerName, measuredSeconds, numberOfElements); {
printf("Sie haben die korrekte Zahl in %.6lf Sekunde(n) gefunden und %u " int score = addHighscore(playerName, measuredSeconds, numberOfElements);
"Punkte erzielt.\n", printf("Sie haben die korrekte Zahl in %.6lf Sekunde(n) gefunden und %u Punkte erzielt.\n", measuredSeconds, score);
measuredSeconds, score); }
} else else
printf("Leider ist %u nicht korrekt. Richtig waere %u gewesen.\n", printf("Leider ist %u nicht korrekt. Richtig waere %u gewesen.\n", userInput, duplicate);
userInput, duplicate);
loadHighscores(highscorePath); loadHighscores(highscorePath);
showHighscores(); showHighscores();
saveHighscores(highscorePath); saveHighscores(highscorePath);
clearHighscores(); clearHighscores();
exitCode = EXIT_SUCCESS; exitCode = EXIT_SUCCESS;
} }
return exitCode; return exitCode;
} }

View File

@ -1,6 +1,5 @@
CC = gcc CC = gcc
FLAGS = -g -Wall -lm FLAGS = -g -Wall -lm
ASAN_FLAGS = -fsanitize=address
ifeq ($(OS),Windows_NT) ifeq ($(OS),Windows_NT)
include makefile_windows.variables include makefile_windows.variables
@ -25,46 +24,19 @@ doble_initial:
# -------------------------- # --------------------------
# Selbst implementiertes Programm bauen # Selbst implementiertes Programm bauen
# -------------------------- # --------------------------
# alle Objektdateien
program_obj_files = stack.o bintree.o numbers.o timer.o highscore.o program_obj_files = stack.o bintree.o numbers.o timer.o highscore.o
# alle ausführbaren Dateien zu ausführbarem Programm linken
doble : main.o $(program_obj_files) doble : main.o $(program_obj_files)
$(CC) $(FLAGS) $^ -o doble $(CC) $(FLAGS) $^ -o doble
# Regel Kompilieren allgemein
$(program_obj_files): %.o: %.c $(program_obj_filesobj_files): %.o: %.c
$(CC) -c $(FLAGS) $^ -o $@ $(CC) -c $(FLAGS) $^ -o $@
# -------------------------- # --------------------------
# Unit Tests # Unit Tests
# -------------------------- # --------------------------
unitTests:
STACK_TEST_BIN = runStackTests echo "needs to be implemented"
NUMBERS_TEST_BIN = runNumbersTests
BINARY_TEST_BIN = runBinaryTests
# --- Stack Tests ---
stackTests: stack.o test_stack.o
$(CC) $(FLAGS) -I$(unityfolder) -o $(STACK_TEST_BIN) stack.o test_stack.o $(unityfolder)/unity.c
test_stack.o: test_stack.c
$(CC) $(FLAGS) -I$(unityfolder) -c test_stack.c -o test_stack.o
# --- Numbers Tests ---
numbersTests: numbers.o bintree.o stack.o test_numbers.o
$(CC) $(FLAGS) -I$(unityfolder) -o $(NUMBERS_TEST_BIN) numbers.o bintree.o stack.o test_numbers.o $(unityfolder)/unity.c
test_numbers.o: test_numbers.c
$(CC) $(FLAGS) -I$(unityfolder) -c test_numbers.c -o test_numbers.o
# --- Binary Tree Tests ---
binaryTests: bintree.o stack.o test_binary.o
$(CC) $(FLAGS) -I$(unityfolder) -o $(BINARY_TEST_BIN) bintree.o stack.o test_binary.o $(unityfolder)/unity.c
test_binary.o: test_binary.c
$(CC) $(FLAGS) -I$(unityfolder) -c test_binary.c -o test_binary.o
# -------------------------- # --------------------------
# Clean # Clean
@ -74,5 +46,4 @@ ifeq ($(OS),Windows_NT)
del /f *.o doble del /f *.o doble
else else
rm -f *.o doble rm -f *.o doble
endif endif

106
numbers.c
View File

@ -1,96 +1,26 @@
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <string.h>
#include "numbers.h" #include "numbers.h"
#include "bintree.h" #include "bintree.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// TODO: getDuplicate und createNumbers implementieren //TODO: getDuplicate und createNumbers implementieren
/**Erzeugen eines Arrays mit der vom Nutzer eingegebenen Anzahl an /* * * Erzeugen eines Arrays mit der vom Nutzer eingegebenen Anzahl an Zufallszahlen.
* Zufallszahlen. Sicherstellen, dass beim Befüllen keine Duplikate entstehen. * Sicherstellen, dass beim Befüllen keine Duplikate entstehen.
* Duplizieren eines zufälligen Eintrags im Array. * Duplizieren eines zufälligen Eintrags im Array.
* in `getDuplicate()`: Sortieren des Arrays und Erkennen der doppelten Zahl * in `getDuplicate()`: Sortieren des Arrays und Erkennen der doppelten Zahl durch Vergleich benachbarter Elemente. */
* durch Vergleich benachbarter Elemente. */
// Returns len random numbers between 1 and 2x len in random order which are all // Returns len random numbers between 1 and 2x len in random order which are all different, except for two entries.
// different, except for two entries. Returns NULL on errors. Use your // Returns NULL on errors. Use your implementation of the binary search tree to check for possible duplicates while
// implementation of the binary search tree to check for possible duplicates // creating random numbers.
// while creating random numbers. unsigned int *createNumbers(unsigned int len)
{
// vergleicht zwei Werte: a<b: -1 a>b: 1 a=b: 0
int compareUnsignedInt(const void *a, const void *b) {
unsigned int x = *(unsigned int *)a;
unsigned int y = *(unsigned int *)b;
return (x < y) ? -1 : (x > y);
} }
unsigned int *createNumbers(unsigned int len) { // Returns only the only number in numbers which is present twice. Returns zero on errors.
if (len < 2) // Duplikat bei zwei Einträgen sinnlos unsigned int getDuplicate(const unsigned int numbers[], unsigned int len)
return NULL; {
unsigned int *numbersArray = malloc( }
sizeof(unsigned int) * len); // Speicher für das Ausgabearray reservieren:
// Größe eines Eintrags * Größe des Arrays
if (!numbersArray) // Speicher konnte nicht reserviert werden
return NULL;
TreeNode *root =
NULL; // Binärbaum zum Generieren der Zufallszahlen ohne Duplikate
for (unsigned int i = 0; i < len; i++) {
unsigned int currentNumber;
int isDuplicate;
do { // mindestens eine Zufallszahl erzeugen
currentNumber = (rand() % (2 * len)) + 1; // Zahlenbereich 1 bis 2*len
isDuplicate = 0;
root = addToTree(root, &currentNumber, sizeof(unsigned int),
compareUnsignedInt,
&isDuplicate); // compareUnsignedInt wird zum Verwenden
// bei Vergleichen übergeben
} while (isDuplicate); // wenn isDuplicate gesetzt wird, muss eine neue Zahl
// erzeugt werden, die Schleife wird wiederholt
numbersArray[i] = currentNumber;
}
// Ein zufälliges Duplikat erzeugen
unsigned int duplicateIndex =
rand() % len; // Index des Duplikats per Zufall bestimmen
unsigned int newIndex;
do {
newIndex = rand() % len;
} while (newIndex == duplicateIndex); // zweiten Index bestimmen, der nicht
// mit dem ersten übereinstimmt
numbersArray[newIndex] =
numbersArray[duplicateIndex]; // Wert vom ersten Index kopieren
clearTree(&root); // Speicher wieder freigeben, wird nicht mehr benötigt
return numbersArray;
}
// 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) { // array numbers, sowie die Länge wird übergeben
if (!numbers || len < 2)
return 0; // fehlerhaftes Array
TreeNode *root = NULL; // leerer Baum
unsigned int duplicateValue = 0; // Wert des Duplikats
for (unsigned int i = 0; i < len && duplicateValue == 0; i++) { // Schleife
int isDuplicate = 0;
// Zahl in den Baum einfügen
root = addToTree(root, &numbers[i], sizeof(unsigned int),
compareUnsignedInt, &isDuplicate);
// Duplikat erkannt
if (isDuplicate && duplicateValue == 0) {
duplicateValue = numbers[i]; // Duplikat merken, for-Schleife wird beendet
}
}
clearTree(&root); // Baum freigeben
return duplicateValue; // 0, falls kein Duplikat
}

View File

@ -1,16 +1,12 @@
#ifndef NUMBERS_H #ifndef NUMBERS_H
#define NUMBERS_H #define NUMBERS_H
int compareUnsignedInt(const void *a, const void *b); // 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
// Returns len random numbers between 1 and 2x len in random order which are all // creating random numbers.
// 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); unsigned int *createNumbers(unsigned int len);
// Returns only the only number in numbers which is present twice. Returns zero // Returns only the only number in numbers which is present twice. Returns zero on errors.
// on errors.
unsigned int getDuplicate(const unsigned int *numbers, unsigned int len); unsigned int getDuplicate(const unsigned int *numbers, unsigned int len);
#endif #endif

Binary file not shown.

99
stack.c
View File

@ -1,100 +1,33 @@
#include "stack.h"
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include "stack.h"
/*typedef struct { //TODO: grundlegende Stackfunktionen implementieren:
void *data;
struct StackNode *next;
struct StackNode *prev;
} StackNode;*/
// TODO: grundlegende Stackfunktionen implementieren:
/* * `push`: legt ein Element oben auf den Stack, /* * `push`: legt ein Element oben auf den Stack,
* `pop`: entfernt das oberste Element, * `pop`: entfernt das oberste Element,
* `top`: liefert das oberste Element zurück, * `top`: liefert das oberste Element zurück,
* `clearStack`: gibt den gesamten Speicher frei. */ * `clearStack`: gibt den gesamten Speicher frei. */
// [A] -> [B] -> [C] -> NULL
// stack -> stack.next
// Funktion zum erstellen neuer nodes
StackNode *createNode(void *data) {
// Speicher reservieren
StackNode *node = malloc(sizeof(StackNode));
// Speicher konnte nicht reserviert werden
if (node == NULL)
return NULL;
node->data = data;
node->next = NULL;
node->prev = NULL;
return node;
}
// Pushes data as pointer onto the stack. // Pushes data as pointer onto the stack.
StackNode *push(StackNode *stack, void *data) { StackNode *push(StackNode *stack, void *data)
{
StackNode *newNode = createNode(data);
// Fehler beim Reservieren des Speichers, stack wird unverändert zurückgegeben
if (newNode == NULL) {
return stack;
}
// der aktuelle Kopf wird der nächste Node
newNode->next = stack;
// bisheriger Kopf bekommt Pointer auf oberstes Element
if (stack != NULL) {
stack->prev = newNode;
}
return newNode; // neuer Kopf wird zurückgegeben
} }
// Deletes the top element of the stack (latest added element) and releases its // Deletes the top element of the stack (latest added element) and releases its memory. (Pointer to data has to be
// memory. (Pointer to data has to be freed by caller.) // freed by caller.)
StackNode *pop(StackNode *stack) { StackNode *pop(StackNode *stack)
{
// Stack ohne Elemente
if (stack == NULL)
return NULL;
// Element unter Kopf wird als nextNode gespeichert
StackNode *nextNode = stack->next;
if (nextNode != NULL) {
nextNode->prev = NULL; // der Zeiger zum Kopf wird auf NULL gesetzt
}
free(stack);
stack = NULL; // Speicher des Kopfes freigeben
return nextNode; // neuen Kopf zurückgeben
} }
// Returns the data of the top element. // Returns the data of the top element.
void *top(StackNode *stack) { void *top(StackNode *stack)
// wenn stack leer ist, wird NULL zurückgegeben {
// Zeiger auf Daten des obersten Elements
return stack ? stack->data : NULL;
} }
// Clears stack and releases all memory. // Clears stack and releases all memory.
void clearStack(StackNode **stack) { // Zeiger auf den Zeiger auf den Stackkopf void clearStack(StackNode *stack)
// verändert den Zeiger selbst, mit *stack lokale Kopie {
// im Aufruf &stack verwenden
while (*stack != NULL) {
(*stack)->prev = NULL; // späteren Pointerzugriff verhindern
StackNode *next = (*stack)->next; // nächstes Element speichern
(*stack)->next = NULL; // späteren Pointerzugriff verhindern
free(*stack); // aktuelles Element freigeben
*stack = next; // Zeiger auf nächsten Knoten setzen
}
} }

24
stack.h
View File

@ -1,35 +1,25 @@
#ifndef STACK_H #ifndef STACK_H
#define STACK_H #define STACK_H
/* A stack is a special type of queue which uses the LIFO (last in, first out) /* A stack is a special type of queue which uses the LIFO (last in, first out) principle.
principle. This means that with each new element all other elements are pushed This means that with each new element all other elements are pushed deeper into the stack.
deeper into the stack. The latest element is taken from the stack. */ The latest element is taken from the stack. */
#include <stdlib.h> #include <stdlib.h>
// TODO: passenden Datentyp als struct anlegen //TODO: passenden Datentyp als struct anlegen
typedef struct StackNode {
void *data;
struct StackNode *next;
struct StackNode *prev;
} StackNode;
StackNode *createNode(void *data);
// Pushes data as pointer onto the stack. // Pushes data as pointer onto the stack.
StackNode *push(StackNode *stack, void *data); StackNode *push(StackNode *stack, void *data);
// Deletes the top element of the stack (latest added element) and releases its // Deletes the top element of the stack (latest added element) and releases its memory. (Pointer to data has to be
// memory. (Pointer to data has to be freed by caller.) // freed by caller.)
StackNode *pop(StackNode *stack); StackNode *pop(StackNode *stack);
// Returns the data of the top element. // Returns the data of the top element.
void *top(StackNode *stack); void *top(StackNode *stack);
// Clears stack and releases all memory. // Clears stack and releases all memory.
void clearStack(StackNode **stack); void clearStack(StackNode *stack);
#endif #endif

View File

@ -1,126 +0,0 @@
#include "unity.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "bintree.h"
int compareUnsignedInt(const void *a, const void *b) {
unsigned int x = *(unsigned int *)a;
unsigned int y = *(unsigned int *)b;
if (x < y)
return -1;
if (x > y)
return 1;
return 0;
}
TreeNode *root = NULL;
void setUp(void) {
root = NULL; // vor jedem Test leeren
}
void tearDown(void) { clearTree(&root); }
// Test, ob addToTree Knoten korrekt hinzufügt
/*TreeNode *addToTree(TreeNode *root, const void *data, size_t dataSize,
CompareFctType compareFct, int *isDuplicate) */
void test_addToTree_basic(void) {
int isDuplicate;
unsigned int testInt = 10;
root = addToTree(root, &testInt, sizeof(testInt), compareUnsignedInt,
&isDuplicate);
TEST_ASSERT_NOT_NULL(root); // Knoten wurde erfolgreich erzeugt
TEST_ASSERT_EQUAL_UINT(
10,
*(unsigned int *)root
->data); // Datenzeiger wurde richtig gesetzt, void pointer auf
// unsigned int pointer casten, mit *wird der Wert abgerufen
TEST_ASSERT_EQUAL_INT(0, isDuplicate); // kein Duplikat
TEST_ASSERT_EQUAL_UINT(1, treeSize(root)); // der tree hat einen Eintrag
}
// Test, dass Duplikate erkannt werden
void test_addToTree_duplicate(void) {
int isDuplicate;
unsigned int val1 = 10, val2 = 10; // Duplikate
root = addToTree(root, &val1, sizeof(val1), compareUnsignedInt,
&isDuplicate); // val 1 zum leeren Baum hinzufügen
TEST_ASSERT_EQUAL_INT(0, isDuplicate); // erster Knoten->kein Duplikat
root = addToTree(root, &val2, sizeof(val2), compareUnsignedInt,
&isDuplicate); // val 2 hinzufügen
TEST_ASSERT_EQUAL_INT(1, isDuplicate); // Duplikat erkannt
TEST_ASSERT_EQUAL_UINT(1,
treeSize(root)); // Duplikate wurde nicht hinzugefügt
}
// Test nextTreeData Traversierung
void test_nextTreeData_in_order(void) {
unsigned int values[] = {20, 10, 30}; // erwartete Ausgabe: 10 -> 20 -> 30
int isDuplicate;
for (int i = 0; i < 3; i++) {
root = addToTree(root, &values[i], sizeof(values[i]), compareUnsignedInt,
&isDuplicate); // Baum füllen
}
unsigned int expected[] = {10, 20, 30}; // erwartet in Order Reihenfolge
int valueID = 0;
void *data;
// Neue Iteration starten
data = nextTreeData(root);
while (data != NULL) {
TEST_ASSERT_EQUAL_UINT(expected[valueID],
*(unsigned int *)data); // entspricht erwartetem Wert
valueID++;
data = nextTreeData(NULL); // weitere Elemente abrufen
}
TEST_ASSERT_EQUAL_INT(3, valueID); // alle 3 Knoten besucht
}
// Testet, dass clearTree Speicher freigibt und Root auf NULL setzt
void test_clearTree_sets_root_null(void) {
int isDuplicate;
unsigned int val1 = 10, val2 = 20;
root = addToTree(root, &val1, sizeof(val1), compareUnsignedInt, &isDuplicate);
root = addToTree(root, &val2, sizeof(val2), compareUnsignedInt, &isDuplicate);
// Vor dem Clear prüfen, dass Root nicht NULL ist
TEST_ASSERT_NOT_NULL(root);
clearTree(&root);
// Nach dem Clear muss Root auf NULL gesetzt sein
TEST_ASSERT_NULL(root);
}
// Test treeSize zählt korrekt
void test_treeSize(void) {
unsigned int testInts[] = {10, 20, 5};
int isDuplicate;
for (int i = 0; i < 3; i++) {
root = addToTree(root, &testInts[i], sizeof(testInts[i]),
compareUnsignedInt, &isDuplicate);
}
TEST_ASSERT_EQUAL_UINT(3, treeSize(root));
}
int main(void) {
UNITY_BEGIN();
printf(
"\n------------------------binarytree test------------------------\n\n");
RUN_TEST(test_addToTree_basic);
RUN_TEST(test_addToTree_duplicate);
RUN_TEST(test_nextTreeData_in_order);
RUN_TEST(test_clearTree_sets_root_null);
RUN_TEST(test_treeSize);
return UNITY_END();
}

View File

@ -1,73 +0,0 @@
#include "unity.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "numbers.h"
#define TEST_ARRAY_LEN 100
// Speicher für ein Array wird reserviert
void test_createNumbers_length(void) { // erstellt ein Array der Länge hundert
unsigned int *testArray = createNumbers(TEST_ARRAY_LEN);
TEST_ASSERT_NOT_NULL(testArray);
free(testArray);
}
// Duplikat ist genau einmal vorhanden
void test_createNumbers_single_duplicate(void) {
unsigned int *testArray = createNumbers(TEST_ARRAY_LEN); // Array erstellen
TEST_ASSERT_NOT_NULL(testArray); // Speicher konnte reserviert werden
unsigned int duplicate =
getDuplicate(testArray, TEST_ARRAY_LEN); // Duplikat holen
TEST_ASSERT_TRUE(duplicate > 0); // Duplikat ist größer als 0
TEST_ASSERT_TRUE(
duplicate <
(2 * TEST_ARRAY_LEN)); // Duplikat liegt im vorgegebenen Zahlenbereich
unsigned int count = 0; // Anzahl der Duplikate
for (unsigned int i = 0; i < TEST_ARRAY_LEN;
i++) { // Einträge des testArrays auf Duplikate prüfen
if (testArray[i] == duplicate) {
count++;
}
}
TEST_ASSERT_EQUAL_UINT(2, count); // Duplikat zwei mal vorhanden
free(testArray); // Speicher freigeben
}
// getDuplicate testen
void test_getDuplicate_manual_array(
void) { // duplikat in fremden array wird gefunden
unsigned int numbers[5] = {10, 20, 30, 40, 20};
unsigned int duplicate = getDuplicate(numbers, 5);
TEST_ASSERT_EQUAL_UINT(20, duplicate);
}
// getDuplicate erkennt fehlerhaftes Array
void test_getDuplicate_invalid_input(void) {
TEST_ASSERT_EQUAL_UINT(
0, getDuplicate(NULL, 5)); // unsigned int getDuplicate(const unsigned int
// *numbers, unsigned int len)
unsigned int testArray[1] = {2};
TEST_ASSERT_EQUAL_UINT(0, getDuplicate(testArray, 1));
}
void setUp(void) {}
void tearDown(void) {}
int main(void) {
UNITY_BEGIN();
printf("\n------------------------numbers test------------------------\n\n");
RUN_TEST(test_createNumbers_length);
RUN_TEST(test_createNumbers_single_duplicate);
RUN_TEST(test_getDuplicate_manual_array);
RUN_TEST(test_getDuplicate_invalid_input);
return UNITY_END();
}

View File

@ -1,144 +0,0 @@
#include "unity.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "stack.h"
// StackNode *createNode(void *data) testen
void test_createNode(void) {
int testInt = 26;
StackNode *testNode = createNode(&testInt); // Adresse des testInts
TEST_ASSERT_NOT_NULL(
testNode); // Speicher konnte reserviert werden, malloc ist nicht NULL
TEST_ASSERT_EQUAL_PTR(&testInt, testNode->data); // data pointer gesetzt
TEST_ASSERT_NULL(testNode->next); // vorheriger und nächster Eintrag NULL
TEST_ASSERT_NULL(testNode->prev);
free(testNode); // Speicher freigeben
}
// StackNode *push(StackNode *stack, void *data) testen
void test_pushDataToStack(void) {
int testInts[] = {27, 28};
StackNode *testStack = NULL; // leeren testStack initialisieren
testStack =
push(testStack, &testInts[0]); // leerer Stack mit Adresse des testInts
TEST_ASSERT_NOT_NULL(testStack); // im Fehlerfall wird testStack unverändert
// zurückgegeben -> bei Fehler NULL
TEST_ASSERT_EQUAL_PTR(&testInts[0], testStack->data); // data pointer gesetzt
TEST_ASSERT_NULL(testStack->next); // vorheriger und nächster pointer auf NULL
// gesetzt, da es nur einen Knoten gibt
TEST_ASSERT_NULL(testStack->prev);
// zweiter Push
StackNode *oldHead = testStack; // bisherigen head speichern
testStack = push(testStack, &testInts[1]);
TEST_ASSERT_NOT_NULL(testStack);
TEST_ASSERT_NOT_EQUAL(
oldHead,
testStack); // bei malloc Fehler wird der head unverändert zurückgegeben
TEST_ASSERT_EQUAL_PTR(&testInts[0],
oldHead->data); // data pointer wurden richtig gesetzt
TEST_ASSERT_EQUAL_PTR(&testInts[1], testStack->data);
// richtige Verkettung: NULL <- testStack -> testStack->next -> oldHead ->
// NULL
TEST_ASSERT_EQUAL_PTR(oldHead, testStack->next);
TEST_ASSERT_EQUAL_PTR(testStack, oldHead->prev);
TEST_ASSERT_NULL(testStack->prev);
// Speicherfreigabe
testStack->next = NULL; // pointer ungültig machen, damit nicht ausversehen
// später aufgerufen
oldHead->prev = NULL;
free(oldHead);
free(testStack);
}
void test_deleteTopElement(void) {
int testInts[] = {10, 20, 30};
StackNode *stack = NULL;
for (int i = 0; i < 3;
i++) { // Stack mit drei Elementen, oberestes Element mit data 30
stack = push(stack, &testInts[i]);
}
TEST_ASSERT_EQUAL_PTR(&testInts[2], stack->data); // oberstes Element ist 30
stack = pop(stack); // oberstes Element löschen
TEST_ASSERT_EQUAL_PTR(&testInts[1], stack->data);
TEST_ASSERT_NULL(
stack->prev); // pointer zum alten head wurde auf NULL gesetzt
stack = pop(stack);
TEST_ASSERT_EQUAL_PTR(&testInts[0], stack->data);
TEST_ASSERT_NULL(stack->prev);
stack = pop(stack); // bei leerem Stack wird NULL zurückgegeben
TEST_ASSERT_NULL(stack);
}
void test_returnData(void) {
int testInts[] = {10, 20, 30};
StackNode *stack = NULL;
for (int i = 0; i < 3; i++) {
stack = push(stack, &testInts[i]);
}
TEST_ASSERT_EQUAL_PTR(&testInts[2],
top(stack)); // top gibt richtige Adresse zurück
stack = pop(stack); // oberstes Element löschen
TEST_ASSERT_EQUAL_PTR(&testInts[1], top(stack));
stack = pop(stack);
TEST_ASSERT_EQUAL_PTR(&testInts[0], top(stack));
stack = pop(stack); // bei leerem Stack wird NULL zurückgegeben
TEST_ASSERT_NULL(stack);
}
void test_clearStack(void) {
int testInts[] = {1, 2, 3, 4, 5};
StackNode *stack = NULL;
for (int i = 0; i < 5; i++) {
stack = push(stack, &testInts[i]);
}
//printf("testints: %d,%d,%d,%d,%d",testInts[0],testInts[1],testInts[2],testInts[3],testInts[4]);
clearStack(&stack);
TEST_ASSERT_NULL(stack);
}
void setUp(void) {}
void tearDown(void) {}
int main(void) {
UNITY_BEGIN();
printf("\n------------------------stack test------------------------\n\n");
RUN_TEST(test_createNode);
RUN_TEST(test_pushDataToStack);
RUN_TEST(test_deleteTopElement);
RUN_TEST(test_returnData);
RUN_TEST(test_clearStack);
return UNITY_END();
}