From fc0ecd6b2768935f383e4012e187c1166bd768f5 Mon Sep 17 00:00:00 2001 From: Bora Date: Thu, 12 Jun 2025 08:10:22 +0200 Subject: [PATCH] halo --- Modul4/automat.c | 208 +++++++++++++++++++++++------------------------ dualrech.c | 67 ++++++++++++--- josephus.c | 43 +++++----- numausg.c | 47 +++++++---- queue.c | 55 ++++++++++--- 5 files changed, 253 insertions(+), 167 deletions(-) diff --git a/Modul4/automat.c b/Modul4/automat.c index 7b2b469..6d3a617 100644 --- a/Modul4/automat.c +++ b/Modul4/automat.c @@ -8,157 +8,149 @@ * * \**********************************************************************/ -#include -#include -#include "automat.h" - +#include // Standard Ein-/Ausgabe +#include // Standardbibliothek (z.B. für malloc) +#include "automat.h" // Eigene Headerdatei für Automatentypen und -funktionen /*--- #defines -------------------------------------------------------*/ /* Macro zur Ermittlung der Array Groesse */ -#define SIZE_OF(a) (sizeof((a))/ sizeof(*(a))) -#define NR_OF_STATES (I-A+1) // Achtung: A=0, I=8, ergibt 9 Zustände - +#define SIZE_OF(a) (sizeof((a))/ sizeof(*(a))) // Gibt die Anzahl der Elemente eines Arrays zurück +#define NR_OF_STATES (I-A + 1) // Anzahl der Zustände (Enum von A bis I) /*--- Datentypen (typedef) -------------------------------------------*/ /* Definition der Zustaende */ -typedef enum {A=0,B,C,D,E,F,G,H,I} state_t; - +typedef enum {A=0,B,C,D,E,F,G,H,I} state_t; // Aufzählung der Zustände von A bis I +/* Definition der fsm-spezifischen Variablen */ /* Struktur zur Beschreibung eines Uebergangs mit "Don't Care"-Moeglichkeit */ typedef struct { - int input; - int mask; - state_t nxtstate; + int input; // Erwarteter Eingabewert (Bitmaske) + int mask; // Maske für relevante Bits + state_t nxtstate; // Zielzustand bei passender Eingabe } fsm_state_t; - /* Struktur zur Beschreibung aller Uebergaenge eines Zustands */ typedef struct { - const fsm_state_t * transitions; - int nrOfTransitions; - state_t defaultNxtState; + const fsm_state_t * transitions; // Zeiger auf Array von Übergängen + int nrOfTransitions; // Anzahl der Übergänge + state_t defaultNxtState; // Standard-Zielzustand, falls keine Transition passt } fsm_full_state_t; - /*--- Modulglobale static Variablen ----------------------------------*/ /* Definition der Zustandsvariablen */ -static state_t s_curstate = A; /* Initialisierung */ - +static state_t s_curstate = A; /* Initialisierung */ // Aktueller Zustand, Start bei A /* Definition aller Zustandsuebergaenge fuer jeden Zustand */ -/* Die Masken sind invertiert, was ungewöhnlich ist, aber beibehalten. */ -static const fsm_state_t s_transitions_A[] = { - /* input mask nxtstate */ - { 0x002, ~0x004, B }, - { 0x003, ~0x004, C } +static const fsm_state_t s_transitions_A[] = +{ /* input mask nxtstate */ + { 0x002, ~0x004, B }, // Übergang zu B bei passender Eingabe + { 0x003, ~0x004, C } // Übergang zu C bei anderer Eingabe }; -static const fsm_state_t s_transitions_B[] = { - { 0x002, ~0x004, C }, - { 0x003, ~0x004, D } +static const fsm_state_t s_transitions_B[] = +{ + { 0x002, ~0x004, C }, + { 0x003, ~0x004, D } }; -static const fsm_state_t s_transitions_C[] = { - { 0x002, ~0x004, D }, - { 0x003, ~0x000, F }, - { 0x007, ~0x000, H } +static const fsm_state_t s_transitions_C[] = +{ + { 0x002, ~0x004, D }, + { 0x003, ~0x000, F }, + { 0x007, ~0x000, H } }; -static const fsm_state_t s_transitions_D[] = { - { 0x002, ~0x000, F }, - { 0x003, ~0x004, E }, - { 0x006, ~0x000, H } +static const fsm_state_t s_transitions_D[] = +{ + { 0x002, ~0x000, F }, + { 0x003, ~0x004, E }, + { 0x006, ~0x000, H } }; -static const fsm_state_t s_transitions_E[] = { - { 0x002, ~0x000, F }, - { 0x003, ~0x004, E }, - { 0x006, ~0x000, H } +static const fsm_state_t s_transitions_E[] = +{ + { 0x002, ~0x000, F }, + { 0x003, ~0x004, E }, + { 0x006, ~0x000, H } }; -static const fsm_state_t s_transitions_F[] = { - { 0x002, ~0x001, G }, - { 0x004, ~0x001, H }, - { 0x006, ~0x001, I } +static const fsm_state_t s_transitions_F[] = +{ + { 0x002, ~0x001, G }, + { 0x004, ~0x001, H }, + { 0x006, ~0x001, I } }; -static const fsm_state_t s_transitions_G[] = { - { 0x002, ~0x001, G }, - { 0x004, ~0x001, H }, - { 0x006, ~0x001, I } +static const fsm_state_t s_transitions_G[] = +{ + { 0x002, ~0x001, G }, + { 0x004, ~0x001, H }, + { 0x006, ~0x001, I } }; -static const fsm_state_t s_transitions_H[] = { - { 0x000, ~0x001, A }, - { 0x002, ~0x000, B }, - { 0x003, ~0x000, C }, - { 0x006, ~0x001, I } +static const fsm_state_t s_transitions_H[] = +{ + { 0x000, ~0x001, A }, + { 0x002, ~0x000, B }, + { 0x003, ~0x000, C }, + { 0x006, ~0x001, I } }; -static const fsm_state_t s_transitions_I[] = { - { 0x000, ~0x001, A }, - { 0x002, ~0x000, B }, - { 0x003, ~0x000, C }, - { 0x006, ~0x001, I } +static const fsm_state_t s_transitions_I[] = +{ + { 0x000, ~0x001, A }, + { 0x002, ~0x000, B }, + { 0x003, ~0x000, C }, + { 0x006, ~0x001, I } }; - /* Definition der Uebergangstabelle */ /* Die Reihenfolge der Zustaende in der enum Definition muss der -* Reihenfolge der Zustaende in der Uebergangstabelle entsprechen */ -static const fsm_full_state_t s_state_table[NR_OF_STATES] = { +* Reihenfolge der Zustaende in der Uebergangstabelle entsprechen +* [Zeile] [Spalte] */ +static const fsm_full_state_t s_state_table[NR_OF_STATES] = +{ /* transitions nrOfTransitions defaultNxtState */ - { s_transitions_A, SIZE_OF(s_transitions_A), A }, - { s_transitions_B, SIZE_OF(s_transitions_B), B }, - { s_transitions_C, SIZE_OF(s_transitions_C), C }, - { s_transitions_D, SIZE_OF(s_transitions_D), A }, - { s_transitions_E, SIZE_OF(s_transitions_E), D }, - { s_transitions_F, SIZE_OF(s_transitions_F), F }, - { s_transitions_G, SIZE_OF(s_transitions_G), F }, - { s_transitions_H, SIZE_OF(s_transitions_H), H }, - { s_transitions_I, SIZE_OF(s_transitions_I), H } -}; - + { s_transitions_A, SIZE_OF(s_transitions_A), A }, // Zustand A + { s_transitions_B, SIZE_OF(s_transitions_B), B }, // Zustand B + { s_transitions_C, SIZE_OF(s_transitions_C), C }, // Zustand C + { s_transitions_D, SIZE_OF(s_transitions_D), D }, // Zustand D + { s_transitions_E, SIZE_OF(s_transitions_E), D }, // Zustand E + { s_transitions_F, SIZE_OF(s_transitions_F), F }, // Zustand F + { s_transitions_G, SIZE_OF(s_transitions_G), F }, // Zustand G + { s_transitions_H, SIZE_OF(s_transitions_H), H }, // Zustand H + { s_transitions_I, SIZE_OF(s_transitions_I), H } // Zustand I + }; /* Definition der Ausgaenge */ -static const fsm_action_t s_out_table[NR_OF_STATES] = { +static const fsm_action_t s_out_table[NR_OF_STATES] = +{ /* display muenz_rueck kaffee_los guthaben, display_string */ - { false, false, false, 0, "Warten" }, /* state A */ - { false, false, false, 1, "1 Euro" }, /* state B */ - { false, false, false, 2, "2 Euro" }, /* state C */ - { false, false, false, 3, "3 Euro" }, /* state D */ - { false, true, false, 3, "3 Euro" }, /* state E */ - { true, false, false, 4, "Becher unterstellen" }, /* state F */ - { true, true, false, 4, "Becher unterstellen" }, /* state G */ - { true, false, true, 0, "Kaffe kommt" }, /* state H */ - { true, true, true, 0, "Kaffe kommt" } /* state I */ + { false, false, false, 0, "Warten" }, /* state A */ + { false, false, false, 1, "1 Euro" }, /* state B */ + { false, false, false, 2, "2 Euro" }, /* state C */ + { false, false, false, 3, "3 Euro" }, /* state D */ + { false, true, false, 3, "3 Euro" }, /* state E */ + { true, false, false, 4, "Becher unterstellen" }, /* state F */ + { true, true, false, 4, "Becher unterstellen" }, /* state G */ + { true, false, true, 0, "Kaffe kommt" }, /* state H */ + { true, true, true, 0, "Kaffe kommt" } /* state I */ }; - /*--- Funktionsdefinition --------------------------------------------*/ -/* Setzt den Automaten in den Startzustand zurück */ void automat_reset(void) { - printf("---- automat_reset ----\n"); - s_curstate = A; + printf("---- automat_reset ----\n"); // Ausgabe zur Kontrolle + s_curstate = A; // Automat in Startzustand (A) zurücksetzen } - -/* Führt einen Zustandsübergang durch, basierend auf den Eingaben */ +/*--- Funktionsdefinition --------------------------------------------*/ void automat_transition(BOOL becher, BOOL muenze, BOOL muenz_wert) { printf("---- automat_transition becher(%0d) muenze(%0d) muenz_wert(%0d) ----\n", - becher, muenze, muenz_wert); - - /* Eingabewert als Bitfeld kodieren: becher=Bit2, muenze=Bit1, muenz_wert=Bit0 */ - int in = (becher << 2) | (muenze << 1) | (muenz_wert << 0); - - const fsm_full_state_t * full_transition = &s_state_table[s_curstate]; - const fsm_state_t * transition = full_transition->transitions; + becher, muenze, muenz_wert); // Eingaben ausgeben + int in = (becher << 2) | (muenze << 1) | (muenz_wert << 0); // Eingabewert als Bitmuster kodieren + const fsm_full_state_t * full_transition = &s_state_table[s_curstate]; // Übergangstabelle für aktuellen Zustand holen + const fsm_state_t * transition = full_transition->transitions; // Zeiger auf Übergänge int i; - - /* Übergänge prüfen */ - for(i = 0; i < full_transition->nrOfTransitions; i++) + for(i = 0; i < full_transition->nrOfTransitions; i++) // Alle möglichen Übergänge prüfen { - /* Maskenlogik: input == (in & mask) */ - if(transition[i].input == (in & transition[i].mask)) + if(transition[i].input == (in & transition[i].mask)) // Prüfen, ob Eingabe zur Transition passt { - s_curstate = transition[i].nxtstate; - break; + s_curstate = transition[i].nxtstate; // In Zielzustand wechseln + break; // Schleife verlassen } } - /* Wenn kein Übergang passt, gehe in den Default-Zustand */ - if(i == full_transition->nrOfTransitions) + if(i == full_transition->nrOfTransitions) // Falls keine Transition gepasst hat { - s_curstate = full_transition->defaultNxtState; + s_curstate = full_transition->defaultNxtState; // In Default-Zustand wechseln } } - -/* Gibt die aktuellen Ausgänge des Automaten zurück */ +/*--- Funktionsdefinition --------------------------------------------*/ fsm_action_t automat_output(void) { - return s_out_table[s_curstate]; + return s_out_table[s_curstate]; // Aktuelle Ausgabewerte für Zustand zurückgeben } -//gcc automat.c view.c main.c io.c checker.c -o console_automat +//gcc automat.c view.c main.c io.c checker.c -o console_automat \ No newline at end of file diff --git a/dualrech.c b/dualrech.c index c09c972..01d9434 100644 --- a/dualrech.c +++ b/dualrech.c @@ -1,38 +1,83 @@ #include #include #include + +/* Prüft, ob der übergebene String nur aus '0' und '1' besteht (also eine Dualzahl ist). Gibt 1 zurück, wenn ja, sonst 0.*/ int ist_dual(const char *s) { - while (*s) if (*s != '0' && *s != '1') return 0; else s++; - return 1; + while (*s) + if (*s != '0' && *s != '1') + return 0; // Nicht erlaubt, also keine Dualzahl + else + s++; // Nächstes Zeichen prüfen + return 1; // Alles ok, Dualzahl } + +/*Gibt die 32-Bit-Binärdarstellung einer Zahl aus. Es werden immer 32 Zeichen (Bits) ausgegeben, auch führende Nullen.*/ void print_bin(int n) { - for (int i = 31; i >= 0; i--) putchar((n >> i) & 1 ? '1' : '0'); + for (int i = 31; i >= 0; i--) + putchar((n >> i) & 1 ? '1' : '0'); } + +/* + * Hauptprogramm: Erwartet 3 Argumente: + * 1. Operand (als Dualzahl, z.B. "1011") + * 2. Operator (als einzelnes Zeichen: + - * / & ^) + * 3. Operand (als Dualzahl) + * Führt die Operation aus und gibt das Ergebnis als Binärzahl und Hexadezimalzahl aus. + */ int main(int argc, char *argv[]) { + // Prüfen, ob genau 3 Argumente übergeben wurden (Programmname + 3 = 4) if (argc != 4) { printf("Richtiger Aufruf: %s \n", argv[0]); return 1; } + + // Argumente zuweisen char *a = argv[1], *op = argv[2], *b = argv[3]; - int ok = 1; - if (!ist_dual(a)) { printf("....... %s ist keine erlaubte Dualzahl\n", a); ok = 0; } - if (!ist_dual(b)) { printf("....... %s ist keine erlaubte Dualzahl\n", b); ok = 0; } - if (strlen(op) != 1 || strchr("+-*/&^", op[0]) == NULL) { - printf("....... %s ist kein erlaubter Operator\n", op); ok = 0; + int ok = 1; // Flag, ob alles gültig ist + + // Prüfen, ob beide Operanden gültige Dualzahlen sind + if (!ist_dual(a)) { + printf("....... %s ist keine erlaubte Dualzahl\n", a); + ok = 0; } + if (!ist_dual(b)) { + printf("....... %s ist keine erlaubte Dualzahl\n", b); + ok = 0; + } + + // Prüfen, ob der Operator ein erlaubtes Zeichen ist + if (strlen(op) != 1 || strchr("+-*/&^", op[0]) == NULL) { + printf("....... %s ist kein erlaubter Operator\n", op); + ok = 0; + } + + // Falls etwas ungültig war, Programm beenden if (!ok) return 1; + + // Dualzahlen in int umwandeln (Basis 2) int x = strtol(a, NULL, 2), y = strtol(b, NULL, 2), r = 0; - if (*op == '/' && y == 0) { printf("Fehler: Division durch 0\n"); return 1; } + + // Division durch 0 abfangen + if (*op == '/' && y == 0) { + printf("Fehler: Division durch 0\n"); + return 1; + } + + // Die gewünschte Operation ausführen switch (*op) { case '+': r = x + y; break; case '-': r = x - y; break; case '*': r = x * y; break; case '/': r = x / y; break; - case '&': r = x & y; break; - case '^': r = x ^ y; break; + case '&': r = x & y; break; // Bitweises UND + case '^': r = x ^ y; break; // Bitweises XOR } + + // Ergebnis ausgeben: Eingabe, Operator, Ergebnis in Binär- und Hexadezimaldarstellung printf("%s %s %s =\n....... ", a, op, b); print_bin(r); printf(" (0x%X)\n", r); + return 0; } \ No newline at end of file diff --git a/josephus.c b/josephus.c index ae349b7..4da3a9c 100644 --- a/josephus.c +++ b/josephus.c @@ -7,7 +7,7 @@ * \**********************************************************************/ /*--- #includes ------------------------------------------------------*/ -#define _CRT_SECURE_NO_WARNINGS //VC++: keine scanf() Warnungen +#define _CRT_SECURE_NO_WARNINGS #include #include "queue.h" /*--- #defines -------------------------------------------------------*/ @@ -16,31 +16,34 @@ /*--- main -----------------------------------------------------------*/ int main(void) { - int n, z, i=1, nr; + int n, z, i=1, nr; // Variablen für Personenanzahl, Schrittweite, Zähler, Rückgabewert scanf do { - printf("Wie viele Personen: "); - nr = scanf("%d", &n); getchar(); - } while (nr != 1 || n < 0); + printf("Wie viele Personen: "); // Benutzer nach Anzahl der Personen fragen + nr = scanf("%d", &n); getchar(); // Eingabe lesen, Rückgabewert speichern, Zeilenumbruch entfernen + } while (nr != 1 || n < 0); // Wiederholen, falls ungültige Eingabe + do { - printf("Wie vielte ist auszusondern: "); - nr = scanf("%d", &z); getchar(); - } while (nr != 1 || z < 0); - for (i = 1; i <= n; i++) // Queue füllen - put(i); - while (!isEmpty()) { - for (i = 1; i < z; i++) { // z-1 Zahlen aus Queue lesen - if (put(get()) == FALSE) { // und wieder am Ende der Queue einfügen - fprintf(stderr, "Fehler beim Einfügen\n"); - return 1; + printf("Wie vielte ist auszusondern: "); // Benutzer nach Schrittweite fragen + nr = scanf("%d", &z); getchar(); // Eingabe lesen, Rückgabewert speichern, Zeilenumbruch entfernen + } while (nr != 1 || z < 0); // Wiederholen, falls ungültige Eingabe + + for (i = 1; i <= n; i++) // Queue füllen + put(i); // Personen mit Nummer 1 bis n in die Queue einfügen + + while (!isEmpty()) { // Solange noch Personen in der Queue sind + for (i = 1; i < z; i++) { // z-1 Personen überspringen + if (put(get()) == FALSE) { // Erste Person aus der Queue nehmen und wieder hinten einfügen + fprintf(stderr, "Fehler beim Einfügen\n"); // Fehlerausgabe, falls put fehlschlägt + return 1; // Programm mit Fehlercode beenden } } - printf("%d, ", get()); // z. Zahl aus Queue lesen und ausgeben - // Diese Zahl nicht mehr einfügen + printf("%d, ", get()); // Die z-te Person aus der Queue nehmen und ausgeben (ausscheiden) + // Diese Person wird nicht mehr eingefügt } - printf("\n"); - return 0; + printf("\n"); // Zeilenumbruch nach Ausgabe aller ausgeschiedenen Personen + return 0; // Programm erfolgreich beenden } //gcc -c queue.c -o queue.o //ar rcs libqueue.a queue.o -//gcc josephus.c -L. -lqueue -o josephus +//gcc josephus.c -L. -lqueue -o josephus \ No newline at end of file diff --git a/numausg.c b/numausg.c index 916145e..cf18daa 100644 --- a/numausg.c +++ b/numausg.c @@ -1,21 +1,34 @@ #include #include + int main(int argc, char *argv[]) { - if (argc < 2) { - printf("Bitte Dateinamen als erstes Argument angeben.\n"); - return 1; - } - FILE *datei = fopen(argv[1], "r"); - if (datei == NULL) { - perror("Fehler beim Öffnen der Datei"); - return 1; - } - char zeile[1024]; - int zeilennummer = 1; - while (fgets(zeile, sizeof(zeile), datei) != NULL) { - printf("%4d: %s", zeilennummer, zeile); - zeilennummer++; - } - fclose(datei); - return 0; + // Prüfen, ob ein Dateiname als Argument übergeben wurde + if (argc < 2) { + printf("Bitte Dateinamen als erstes Argument angeben.\n"); + return 1; // Fehlercode zurückgeben und Programm beenden + } + + // Datei im Lesemodus ("r") öffnen + FILE *datei = fopen(argv[1], "r"); + if (datei == NULL) { + // Fehler beim Öffnen der Datei, z.B. Datei existiert nicht + perror("Fehler beim Öffnen der Datei"); + return 1; // Fehlercode zurückgeben und Programm beenden + } + + char zeile[1024]; // Puffer für eine Zeile (max. 1023 Zeichen + '\0') + int zeilennummer = 1; // Startwert für die Zeilennummerierung + + // Solange noch Zeilen gelesen werden können + while (fgets(zeile, sizeof(zeile), datei) != NULL) { + // Zeilennummer und Inhalt der Zeile ausgeben + // %4d: Zeilennummer rechtsbündig mit mindestens 4 Stellen + printf("%4d: %s", zeilennummer, zeile); + zeilennummer++; // Zeilennummer erhöhen + } + + // Datei schließen + fclose(datei); + + return 0; // Erfolgreiches Programmende } \ No newline at end of file diff --git a/queue.c b/queue.c index c83c6af..3d29ab6 100644 --- a/queue.c +++ b/queue.c @@ -3,52 +3,85 @@ * queue.c - realisiert eine Queue (Warteschlange) * * Datum: Autor: -* 11.06.2025 OpenAI (auf Basis von Prof. Herold) +* \**********************************************************************/ #include #include #include "queue.h" + /*--- Struktur eines Listenelements ----------------------------------*/ +/* + * Ein Listenelement (Node) besteht aus: + * - value: dem gespeicherten Wert (hier ein int) + * - next: Zeiger auf das nächste Element in der Liste + */ typedef struct Node { int value; struct Node *next; } Node; + /*--- Modulglobale Variablen: Zeiger auf Kopf und Ende der Liste -----*/ +/* + * head: Zeigt auf das erste Element der Queue (Kopf) + * tail: Zeigt auf das letzte Element der Queue (Ende) + * Sind beide NULL, ist die Queue leer. + */ static Node *head = NULL; static Node *tail = NULL; + /*--- put(): Einfügen am Ende der Liste ------------------------------*/ +/* + * Fügt eine neue Zahl am Ende der Queue ein. + * Rückgabewert: TRUE bei Erfolg, FALSE bei Speicherfehler. + */ Bool put(int zahl) { + // Speicher für neues Element reservieren Node *newNode = (Node *)malloc(sizeof(Node)); if (newNode == NULL) { fprintf(stderr, "Speicher konnte nicht allokiert werden.\n"); - return FALSE; + return FALSE; // Fehler: kein Speicher verfügbar } - newNode->value = zahl; - newNode->next = NULL; + newNode->value = zahl; // Wert setzen + newNode->next = NULL; // Am Ende zeigt next auf NULL + if (tail != NULL) { + // Es gibt schon Elemente: neues Element ans Ende anhängen tail->next = newNode; } else { - head = newNode; // Liste war leer + // Die Liste war leer: head zeigt jetzt auf das neue Element + head = newNode; } + // tail zeigt immer auf das letzte Element tail = newNode; return TRUE; } + /*--- get(): Entfernt das erste Element ------------------------------*/ +/* + * Entfernt das erste Element (Kopf) der Queue und gibt dessen Wert zurück. + * Ist die Queue leer, wird QLEER zurückgegeben und eine Fehlermeldung ausgegeben. + */ int get(void) { if (head == NULL) { + // Die Queue ist leer fprintf(stderr, "Fehler: Queue ist leer.\n"); return QLEER; } - Node *tmp = head; - int value = tmp->value; - head = head->next; + Node *tmp = head; // Temporärer Zeiger auf das erste Element + int value = tmp->value; // Wert des ersten Elements speichern + head = head->next; // Kopf auf das nächste Element setzen if (head == NULL) { - tail = NULL; // Liste ist jetzt leer + // Nach dem Entfernen ist die Queue leer, also tail auch auf NULL setzen + tail = NULL; } - free(tmp); - return value; + free(tmp); // Speicher des entfernten Elements freigeben + return value; // Wert zurückgeben } + /*--- isEmpty(): Prüft, ob Liste leer ist ----------------------------*/ +/* + * Gibt TRUE zurück, wenn die Queue leer ist, sonst FALSE. + */ Bool isEmpty(void) { return head == NULL ? TRUE : FALSE; } \ No newline at end of file