In Vorlesung 5 habt ihr Verzweigungen kennengelernt (if, else if, else, switch). In Vorlesung 6 sind die Schleifen dazugekommen (for, while, do-while).
Heute setzt ihr beides um â von kleinen Verzweigungs-Aufgaben bis zu Programmen, die Verzweigungen + Schleifen kombinieren. Damit habt ihr die wichtigsten Bausteine, um nicht-triviale Programme zu schreiben.
if/else if/else, switch/case, logische & Vergleichs-Operatoren sicher anwenden
for, while, do-while bewusst auswĂ€hlen â je nach Problem
Verzweigung + Schleife zusammen einsetzen (FizzBuzz, Zahlenrate)
Endlosschleife · Off-by-One · ganzzahlige Division · = vs ==
Ziel: mehrere Vergleiche hintereinander mit if/else if/else verkette.
Schreibe ein Programm, das eine Temperatur (in Grad Celsius) einliest und sie wie folgt klassifiziert:
| Eingabe | Erwartete Ausgabe |
|---|---|
| -5 | eiskalt |
| 5 | kalt |
| 18 | kĂŒhl |
| 22 | angenehm |
| 35 | heiĂ |
else if (t < 10) â die Bedingung âmindestens 0" ist dann implizit, weil t < 0 schon abgegriffen wurde.
#include <stdio.h>
int main(void) {
int t;
printf("Temperatur in °C: ");
scanf("%d", &t);
if (t < 0) {
printf("eiskalt\n");
} else if (t < 10) {
printf("kalt\n");
} else if (t < 20) {
printf("kuehl\n");
} else if (t < 30) {
printf("angenehm\n");
} else {
printf("heiss\n");
}
return 0;
}
Warum reicht t < 10 fĂŒr â0 bis < 10"? Weil der vorige if-Zweig (t < 0) den negativen Fall schon erwischt hat. In else if sind wir garantiert bei t â„ 0.
Ziel: Logische Operatoren && (UND), || (ODER) und der Modulo-Operator % kombiniert.
Ein Jahr ist ein Schaltjahr, wenn:
Lies ein Jahr ein und gib aus âSchaltjahr" oder âkein Schaltjahr".
| Jahr | Erwartet | Warum? |
|---|---|---|
| 2024 | Schaltjahr | durch 4, nicht durch 100 |
| 2023 | kein Schaltjahr | nicht durch 4 |
| 2000 | Schaltjahr | durch 400 |
| 1900 | kein Schaltjahr | durch 100, aber nicht durch 400 |
| 2100 | kein Schaltjahr | durch 100, aber nicht durch 400 |
jahr % 4 == 0 && (jahr % 100 != 0 || jahr % 400 == 0). Die Klammern um den ODER-Teil sind wichtig â sonst wird die Reihenfolge falsch ausgewertet.
#include <stdio.h>
int main(void) {
int jahr;
printf("Jahr: ");
scanf("%d", &jahr);
if (jahr % 4 == 0 && (jahr % 100 != 0 || jahr % 400 == 0)) {
printf("Schaltjahr\n");
} else {
printf("kein Schaltjahr\n");
}
return 0;
}
Alternative mit verschachtelten if (manche finden das lesbarer):
if (jahr % 400 == 0) printf("Schaltjahr\n");
else if (jahr % 100 == 0) printf("kein Schaltjahr\n");
else if (jahr % 4 == 0) printf("Schaltjahr\n");
else printf("kein Schaltjahr\n");
Ziel: mit FlieĂkomma-Zahlen rechnen + Mehrfachverzweigung. Auffrischung von Datentypen aus VL 4.
BMI = Gewicht (kg) / (GröĂe (m) Ă GröĂe (m))
Lies Gewicht (kg) und GröĂe (in Metern, z.B. 1.75) ein. Gib den BMI mit einer NachkommaÂstelle aus und die Kategorie.
| Gewicht | GröĂe | BMI | Kategorie |
|---|---|---|---|
| 70 | 1.80 | 21.6 | Normalgewicht |
| 55 | 1.70 | 19.0 | Normalgewicht |
| 90 | 1.65 | 33.1 | Adipositas |
| 45 | 1.65 | 16.5 | Untergewicht |
5 / 2 = 2 (Ganzzahl-Division), aber 5.0 / 2.0 = 2.5 (FlieĂkomma). Wenn du Gewicht/GröĂe einliest, nutze double mit %lf bei scanf. Sonst gibt's komische Rundungs-Effekte.
#include <stdio.h>
int main(void) {
double gewicht, groesse;
printf("Gewicht (kg): ");
scanf("%lf", &gewicht);
printf("Groesse (m, z.B. 1.75): ");
scanf("%lf", &groesse);
double bmi = gewicht / (groesse * groesse);
printf("BMI: %.1f -> ", bmi);
if (bmi < 18.5) {
printf("Untergewicht\n");
} else if (bmi < 25.0) {
printf("Normalgewicht\n");
} else if (bmi < 30.0) {
printf("Uebergewicht\n");
} else {
printf("Adipositas\n");
}
return 0;
}
Wichtig: %lf beim scanf (mit âl" fĂŒr âlong" â bei double). Bei printf reicht %f oder %.1f (fĂŒr eine Nachkommastelle).
Ziel: switch/case als Alternative zu vielen if/else if einsetzen â wenn man auf genaue Werte prĂŒft.
Lies zwei Zahlen ein und einen Operator (+, -, *, /). Gib das Ergebnis aus. Bei unbekannten Operatoren: Fehlermeldung. Bei Division durch 0: Fehlermeldung.
| Eingabe | Erwartet |
|---|---|
| 5 + 3 | 8.0 |
| 10 - 4 | 6.0 |
| 7 * 6 | 42.0 |
| 20 / 4 | 5.0 |
| 10 / 0 | Fehler: Division durch 0 |
| 5 ? 3 | Fehler: unbekannter Operator |
scanf(" %c", &op) ein â achtet auf das Leerzeichen vor %c! Es ĂŒberspringt sonst-stehengebliebene Whitespaces (z.B. das Enter nach der vorherigen Zahl).
switch klarer als 4-mal else if. Sobald die Bedingungen unterschiedliche Vergleiche sind (z.B. â<", â>", Ranges), bleibt if/else die richtige Wahl.
#include <stdio.h>
int main(void) {
double a, b;
char op;
printf("Erste Zahl: ");
scanf("%lf", &a);
printf("Operator (+,-,*,/): ");
scanf(" %c", &op); // Leerzeichen vor %c!
printf("Zweite Zahl: ");
scanf("%lf", &b);
switch (op) {
case '+':
printf("%.1f\n", a + b);
break;
case '-':
printf("%.1f\n", a - b);
break;
case '*':
printf("%.1f\n", a * b);
break;
case '/':
if (b == 0) {
printf("Fehler: Division durch 0\n");
} else {
printf("%.1f\n", a / b);
}
break;
default:
printf("Fehler: unbekannter Operator\n");
}
return 0;
}
Wichtig: break; nach jedem case â sonst âfĂ€llt" die AusfĂŒhrung in den nĂ€chsten Fall durch (fall-through). Beim letzten case oder default ist break formal nicht nötig, aber guter Stil.
Ziel: erste for-Schleife mit Akkumulator. Plus: vergleichen mit der GauĂ-Formel.
n ein.1 + 2 + 3 + ⊠+ n.n * (n + 1) / 2.| n | Summe |
|---|---|
| 10 | 55 |
| 100 | 5050 |
| 1000 | 500500 |
int summe = 0; // Akkumulator vor der Schleife auf 0!
for (int i = 1; i <= n; i++) {
summe = summe + i; // gleichwertig: summe += i;
}
Wichtig: summe muss vor der Schleife auf 0 gesetzt werden â sonst zĂ€hlt der erste Durchgang einen Zufallswert dazu.
#include <stdio.h>
int main(void) {
int n;
printf("n: ");
scanf("%d", &n);
// Variante 1: Schleife
int summe = 0;
for (int i = 1; i <= n; i++) {
summe = summe + i;
}
printf("Schleife: %d\n", summe);
// Variante 2: GauĂ-Formel
int formel = n * (n + 1) / 2;
printf("Formel: %d\n", formel);
return 0;
}
Ziel: Schleife in Schleife â und sehen, wie sich die Iterationen multiplizieren.
Gib eine 10Ă10-Multiplikationstabelle aus â von 1Ă1 bis 10Ă10:
1 2 3 4 5 6 7 8 9 10 2 4 6 8 10 12 14 16 18 20 3 6 9 12 15 18 21 24 27 30 ... 10 20 30 40 50 60 70 80 90 100
i (Zeile) von 1 bis 10j (Spalte) von 1 bis 10i * j mit %4d (4-stellig rechtsbĂŒndig)printf("\n");Antwort: genau wie wir lesen â eine Zeile nach der anderen, jede Zeile von links nach rechts. Der Grund: die Ă€uĂere Schleife (Zeile) bewegt sich langsam, die innere Schleife (Spalte) bewegt sich schnell. Pro Wert von i lĂ€uft j einmal komplett von 1 bis 10 â erst dann wechselt i.
Trace fĂŒr die ersten 12 Iterationen (i, j):
i=1: (1,1) (1,2) (1,3) (1,4) (1,5) (1,6) (1,7) (1,8) (1,9) (1,10) â Zeile 1 fertig i=2: (2,1) (2,2) ⊠â jetzt Zeile 2
Merke: wenn ihr die Schleifen tauscht (j auĂen, i innen), kommt eine andere Ausgabe-Reihenfolge â z.B. spaltenweise statt zeilenweise. Ausprobieren!
#include <stdio.h>
int main(void) {
for (int i = 1; i <= 10; i++) {
for (int j = 1; j <= 10; j++) {
printf("%4d", i * j);
}
printf("\n");
}
return 0;
}
%4d druckt eine Ganzzahl rechtsbĂŒndig in einer 4-Zeichen-Spalte â so haben alle Zahlen die gleiche Breite und die Spalten richten sich aus.
Ziel: eine Schleife in nicht-ganzen Schritten laufen lassen â z.B. 0.0, 0.5, 1.0, 1.5, âŠ
Bisher hatten alle eure for-Schleifen eine Ganzzahl als ZĂ€hler (int i, mit i++ oder i--). Wenn ihr aber Schritte wie 0.5, 0.1 oder 0.25 braucht, mĂŒsst ihr zwei Dinge Ă€ndern:
double (nicht int) â sonst werden 0.5-Schritte abgeschnitteni++ schreibt ihr i += 0.5 (gleichwertig: i = i + 0.5)for (double x = 0.0; x <= 3.0; x += 0.5) {
printf("%.1f\n", x);
}
// Ausgabe: 0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0
Bei 0.1 oder 0.3 als Schrittweite kann es passieren, dass die Zahlen nicht exakt sind â z.B. wird aus zehn 0.1-Schritten nicht genau 1.0, sondern 0.9999999. Das liegt daran, dass double binĂ€r gespeichert wird und manche Dezimalzahlen nicht genau abbildbar sind.
Sichere Alternative: nimm einen int-ZĂ€hler und teile am Ende:
for (int i = 0; i <= 6; i++) {
double x = i * 0.5;
printf("%.1f\n", x);
}
Bei 0.5 ist's noch unkritisch (0.5 ist exakt darstellbar), bei 0.1 unbedingt die int-Variante nehmen.
Schreibe ein Programm, das eine Umrechnungs-Tabelle Inch â Zentimeter ausgibt â von 0 inch bis 5 inch in 0.5-Schritten. Formel: cm = inch · 2.54.
0.0 inch = 0.00 cm 0.5 inch = 1.27 cm 1.0 inch = 2.54 cm 1.5 inch = 3.81 cm 2.0 inch = 5.08 cm ... 5.0 inch = 12.70 cm
%4.1f fĂŒr die Inch-Spalte (4 Zeichen breit, 1 Nachkomma)%5.2f fĂŒr die cm-Spalte (5 Zeichen breit, 2 Nachkommastellen)x <= 5.0 als Bedingung, aber x == 5.0 wĂ€re nicht verlĂ€sslich? â Tipp: denk an die FlieĂkomma-Ungenauigkeit. Wenn x durch viele Additionen entstanden ist, ist es vielleicht 4.99999 oder 5.00001 â aber selten exakt 5.0.
Variante A â direkt mit double-ZĂ€hler:
#include <stdio.h>
int main(void) {
for (double inch = 0.0; inch <= 5.0; inch += 0.5) {
double cm = inch * 2.54;
printf("%4.1f inch = %5.2f cm\n", inch, cm);
}
return 0;
}
Variante B â sicher mit int-ZĂ€hler (empfohlen fĂŒr kleinere Schritte wie 0.1):
#include <stdio.h>
int main(void) {
// 0 bis 10 entspricht 0.0 bis 5.0 in 0.5-Schritten (11 Werte)
for (int i = 0; i <= 10; i++) {
double inch = i * 0.5;
double cm = inch * 2.54;
printf("%4.1f inch = %5.2f cm\n", inch, cm);
}
return 0;
}
Warum gibt's zwei Varianten? Variante A ist einfacher zu lesen, funktioniert fĂŒr 0.5 prima. Variante B ist robuster â bei sehr kleinen Schrittweiten (0.1, 0.01) summieren sich Rundungsfehler. Im Beruf sieht man fast immer Variante B, weil sie auch bei langen Tabellen verlĂ€sslich bleibt.
Ziel: die typische Anwendung von do-while â eine Eingabe einlesen und so lange wiederholen, bis sie gĂŒltig ist.
Frage den Benutzer nach einer Zahl zwischen 1 und 100. Solange die Eingabe auĂerhalb dieses Bereichs ist, frage erneut. Bei gĂŒltiger Eingabe gib âDanke: <Zahl>" aus.
Gib eine Zahl zwischen 1 und 100: 150 Ungueltig. Nochmal: -3 Ungueltig. Nochmal: 42 Danke: 42
do-while garantiert das: erst Body ausfĂŒhren, dann Bedingung prĂŒfen.while mĂŒsste man zahl kĂŒnstlich auf einen ungĂŒltigen Wert initialisieren (âTrick"), um die Schleife zumindest einmal zu durchlaufen. Mit do-while entfĂ€llt das.
#include <stdio.h>
int main(void) {
int zahl;
do {
printf("Gib eine Zahl zwischen 1 und 100: ");
scanf("%d", &zahl);
if (zahl < 1 || zahl > 100) {
printf("Ungueltig. Nochmal: ");
}
} while (zahl < 1 || zahl > 100);
printf("Danke: %d\n", zahl);
return 0;
}
Hinweis: Beachte das Semikolon nach while (...) am Ende â bei do-while gehört es dazu. Bei normalem while nicht.
Ziel: Verzweigung und Schleife zusammen einsetzen.
Das Programm âdenkt" sich eine geheime Zahl zwischen 1 und 100. Der Benutzer rĂ€t. Bei jedem Tipp sagt das Programm:
ZĂ€hle die Versuche mit.
Dein Tipp: 50 zu hoch Dein Tipp: 25 zu niedrig Dein Tipp: 42 richtig! Versuche: 3
FĂŒr die erste Version: nimm die geheime Zahl fest im Code (z.B. int geheim = 42;). Echte Zufallszahlen mit rand() kommen spĂ€ter.
for. Es passt zu while oder do-while. do-while ist klassisch: erst raten, dann prĂŒfen.if/else if/else) fĂŒr âzu niedrig" / âzu hoch" / ârichtig".
#include <stdio.h>
int main(void) {
int geheim = 42; // fest fuer die erste Version
int tipp;
int versuche = 0;
do {
printf("Dein Tipp: ");
scanf("%d", &tipp);
versuche++;
if (tipp < geheim) {
printf("zu niedrig\n");
} else if (tipp > geheim) {
printf("zu hoch\n");
} else {
printf("richtig! Versuche: %d\n", versuche);
}
} while (tipp != geheim);
return 0;
}
Bonus fĂŒr spĂ€ter: echte Zufallszahl mit rand():
#include <stdlib.h> #include <time.h> srand(time(NULL)); // Zufallsgenerator initialisieren int geheim = rand() % 100 + 1; // 1 bis 100
Ziel: der berĂŒhmteste Programmier-Test der Welt â viele Firmen fragen ihn im VorstellungsgesprĂ€ch. Mit dem, was ihr heute gelernt habt, könnt ihr ihn locker lösen.
Gib die Zahlen 1 bis 30 aus â aber mit Sonderregeln:
Fizz ausBuzz ausFizzBuzz aus1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz 16 17 Fizz 19 Buzz Fizz 22 23 Fizz Buzz 26 Fizz 28 29 FizzBuzz
ifs ohne else, einer fĂŒr 3, einer fĂŒr 5. Plus ein Flag, um zu wissen, ob schon was ausgegeben wurde.
#include <stdio.h>
int main(void) {
for (int i = 1; i <= 30; i++) {
if (i % 15 == 0) {
printf("FizzBuzz ");
} else if (i % 3 == 0) {
printf("Fizz ");
} else if (i % 5 == 0) {
printf("Buzz ");
} else {
printf("%d ", i);
}
}
printf("\n");
return 0;
}
Warum die Reihenfolge wichtig ist: bei i=15 sind alle drei Bedingungen (durch 3, durch 5, durch 15) wahr. Da if/else if nur den ersten wahren Zweig nimmt, mĂŒssen wir die strengste Bedingung zuerst prĂŒfen.
if/else if/else-Ketten mit mehreren Bedingungen sicher aufbauen&&, ||, ! richtig kombinieren â inkl. Klammernswitch/case einsetzen, wenn ihr auf genaue Werte prĂŒft (vergiss nicht break!)for-Schleife mit Akkumulator-Muster schreiben (Summe, Produkt, ZĂ€hler)while fĂŒr âsolange Bedingung wahr" und do-while fĂŒr âmindestens einmal" unterscheidenBevor du gehst, beantworte fĂŒr dich:
â Diese Reflexion ist freiwillig â aber sie zementiert das Gelernte.
Die Passwörter stehen unten â frei zugĂ€nglich. Bitte fair spielen: erst selbst probieren, dann mit der Musterlösung vergleichen. Eine Lösung, die ihr nur abgeschrieben habt, hilft euch in der Klausur nicht.
| Aufgabe | Thema | Passwort |
|---|---|---|
| Aufgabe 1 | Temperatur-Klassifikator | temperatur |
| Aufgabe 2 | Schaltjahr | schaltjahr |
| Aufgabe 3 | BMI-Rechner | bmi |
| Aufgabe 4 | Taschenrechner (switch) | rechner |
| Aufgabe 5 | Summe 1 bis N | gauss |
| Aufgabe 6 | Einmaleins (verschachtelt) | einmaleins |
| Aufgabe 7 | FlieĂkomma-Schleife (Schrittweite 0.5) | inch |
| Aufgabe 8 | Eingabe validieren (do-while) | validieren |
| Aufgabe 9 | Zahlenrate-Spiel | raten |
| Aufgabe 10 | FizzBuzz (Bonus) | fizzbuzz |
© 2026 HTW Berlin · Prof. Dr. Alexandra Mikityuk