Kapitel 7 Unit 36 von 36 5 Übungen + Bonus Dauer: ~100 Min.
Ömer
Ömer sagt:

Das ist das letzte Arbeitsblatt des Kurses — und eines der wichtigsten! Du lernst heute, wie echte C-Projekte strukturiert sind. Schreibe eigene Header-Dateien, implementiere Module und baue ein komplettes Drei-Datei-Projekt. Das ist das, was professionelle Entwickler jeden Tag tun. 💪

.h von .c unterscheiden Include Guards schreiben Eigene Header erstellen Module implementieren Makefile verstehen
Übung 1

Verstehen: Gehört in .h oder .c?

Unten siehst du verschiedene Code-Fragmente. Ordne jedes zu: Schreibe H (Header/.h) oder C (Quelldatei/.c) in die Spalte "Gehört in".

Code-Fragment Gehört in Begründung
int berechne(int x, int y);
int berechne(int x, int y) { return x * y + 2; }
#define MAX_WERT 100
typedef struct { int x; int y; } Punkt;
int zaehler = 0; (Globale Variable)
extern int zaehler;
static void hilfs_funktion() { ... }
void drucke_ergebnis(float wert);
Deklarationen (Prototypen ohne {}) und Typdefinitionen gehören in .h. Definitionen (mit vollständigem Funktionsrumpf {}) und Variablendefinitionen gehören in .c.
Übung 2

Include Guard schreiben

Schreibe den vollständigen Include Guard für eine Header-Datei namens geometrie.h. Der Guard soll die Konvention für den Makro-Namen einhalten. Fülle die Lücken aus:

/* Datei: geometrie.h */ #ifndef ______________________ #define ______________________ /* Hier kommen die Deklarationen */ float flaeche_kreis(float radius); float umfang_kreis(float radius); float flaeche_rechteck(float breite, float hoehe); float umfang_rechteck(float breite, float hoehe); #______ /* ______________________ */

Erkläre in eigenen Worten, was passiert wenn geometrie.h zweimal von verschiedenen Dateien eingebunden wird:

Konvention: Dateiname in Großbuchstaben, Punkt wird zu Unterstrich. geometrie.h → GEOMETRIE_H
Übung 3

Header-Datei schreiben: string_utils.h

Schreibe eine vollständige Header-Datei string_utils.h mit den folgenden Anforderungen:

/* Datei: string_utils.h */ /* Deine Lösung hier ... */
Ein vollständiger Header: Guard-Anfang → Includes → Deklarationen → Guard-Ende. Keine Funktionsrümpfe mit {}!
Übung 4

Implementierung: string_utils.c

Implementiere die drei Funktionen aus Übung 3 in der Datei string_utils.c. Vergiss nicht, am Anfang #include "string_utils.h" und eventuell weitere nötige Includes einzubinden.

Hinweise:

/* Datei: string_utils.c */ #include "string_utils.h" #include int count_chars(char *s, char c) { /* Deine Implementierung ... */ } void reverse_string(char *s) { /* Deine Implementierung ... */ } int is_palindrome(char *s) { /* Deine Implementierung ... */ }
Für is_palindrome: kopiere den String, kehre die Kopie um mit reverse_string, dann vergleiche mit strcmp. Oder vergleiche direkt s[0] mit s[len-1], s[1] mit s[len-2] usw.
Übung 5

Vollständiges 3-Datei-Projekt: geometrie-Modul

Schreibe ein vollständiges Drei-Datei-Projekt für ein geometrie-Modul. Das Modul soll Funktionen für Kreis und Rechteck bereitstellen.

Geforderte Funktionen:

Funktion Parameter Rückgabe
flaecheKreis float radius float — π × r²
umfangKreis float radius float — 2 × π × r
flaecheRechteck float breite, float hoehe float — breite × hoehe
umfangRechteck float breite, float hoehe float — 2 × (breite + hoehe)

Datei 1 — geometrie.h (Header mit Include Guard und Deklarationen):

/* Datei: geometrie.h */

Datei 2 — geometrie.c (Implementierung aller vier Funktionen, PI = 3.14159f):

/* Datei: geometrie.c */ #include "geometrie.h" /* Tipp: #define PI 3.14159f */

Datei 3 — main.c (Hauptprogramm: berechnet und gibt Ergebnisse für Kreis r=5 und Rechteck 4×7 aus):

/* Datei: main.c */ #include <stdio.h> #include "geometrie.h" int main() { /* Kreis mit Radius 5 */ /* Rechteck 4 x 7 */ return 0; }

GCC-Befehl zum Kompilieren (schreibe den vollständigen Befehl):

Erwartete Ausgabe (berechne selbst oder nutze den Taschenrechner):

PI × 5² = 3.14159 × 25 ≈ 78.54. Nutze printf mit %.2f für zwei Nachkommastellen. Im GCC-Befehl: gcc main.c geometrie.c -o geometrie
Bonus – Makefile

Makefile für das geometrie-Projekt

Ein Makefile automatisiert die Kompilierung. Unten ist ein vollständiges Makefile für das Projekt aus Übung 5 — lies es durch und beantworte dann die Fragen.

# Makefile für das geometrie-Projekt
all: programm
programm: main.o geometrie.o
gcc main.o geometrie.o -o programm
main.o: main.c geometrie.h
gcc -c main.c
geometrie.o: geometrie.c geometrie.h
gcc -c geometrie.c
clean:
rm -f *.o programm

Beantworte die folgenden Fragen zum Makefile:

1. Was bewirkt der Befehl make ohne Argumente?

2. Warum steht geometrie.h als Abhängigkeit von main.o und geometrie.o?

3. Was macht make clean?

4. Du änderst nur geometrie.c. Welche Dateien muss make neu erzeugen?

Erweitere das Makefile: Füge ein neues Modul statistik (statistik.c / statistik.h) hinzu. Schreibe die zwei neuen Regeln:

/* Füge hier die neue programm-Regel (mit statistik.o) und die statistik.o-Regel ein: */
Ein Makefile-Befehl (die Zeile mit gcc) MUSS mit einem echten Tab eingerückt sein — nicht mit Leerzeichen! Das ist eine häufige Fehlerquelle.

Reflexion: Was habe ich gelernt?

✅ Musterlösungen (Kurzübersicht)

Übung 1 — Gehört in .h: Prototyp, #define, typedef struct, extern int zaehler, Prototyp mit void.
Gehört in .c: Funktionsdefinition mit {}, int zaehler = 0; (Definition), static void.

Übung 2 — Include Guard: #ifndef GEOMETRIE_H / #define GEOMETRIE_H / … / #endif /* GEOMETRIE_H */

Übung 5 — GCC-Befehl: gcc main.c geometrie.c -o geometrie (oder mit Makefile: make)

Erwartete Ausgabe: Fläche Kreis (r=5) ≈ 78.54, Umfang Kreis ≈ 31.42, Fläche Rechteck (4×7) = 28.00, Umfang Rechteck = 22.00