Grundlagen der Programmierung
Prof. Dr. Alexandra Mikityuk
HTW Berlin
Stellt euch vor, ihr sollt âHallo!" fĂźnfmal auf den Bildschirm schreiben â ohne Schleifen:
printf("Hallo!\n");
printf("Hallo!\n");
printf("Hallo!\n");
printf("Hallo!\n");
printf("Hallo!\n");
Und bei tausend Wiederholungen? 1000 Zeilen Code? Niemals.
for (int i=0; i<5; i++) {
printf("Hallo!\n");
}
Drei Zeilen â und fĂźr 1000 ändert sich nur eine Zahl. Daher: Schleifen.
âWiederhole genau n-mal." Wenn ich vorher weiĂ, wie oft.
for (i=0; i<n; i++)
âWiederhole solange die Bedingung wahr ist." Wenn ich nicht weiĂ, wie oft.
while (bedingung)
Wie while â aber mindestens einmal garantiert. Bedingung wird am Ende geprĂźft.
do {âŚ} while (bedingung)
Drei Teile in einer Zeile â alle in Klammern, durch Semikolons getrennt.
for (int i = 0; i < 5; i++) {
â â â
â Initialisierung ⥠Bedingung ⢠Schritt
printf("Hallo!\n");
}
Wird einmal ausgefßhrt, ganz am Anfang. Hier wird typisch der Zähler gesetzt.
Wird vor jedem Durchgang geprĂźft. Solange wahr â weitermachen.
Wird nach jedem Durchgang ausgefßhrt. Bringt den Zähler weiter.
Reihenfolge: Init â Check â Body â Schritt â Check â Body â ⌠â Check (nein) â Ende.
for (int i=0; i<3; i++) printf("%d ", i);
| Durchgang | i vor Check | Bedingung | Ausgabe | nach Schritt |
|---|---|---|---|---|
| 1 | 0 | 0 < 3 â | 0 | i = 1 |
| 2 | 1 | 1 < 3 â | 1 | i = 2 |
| 3 | 2 | 2 < 3 â | 2 | i = 3 |
| â | 3 | 3 < 3 â | â | Schleife endet |
// Gib die Zahlen 1 bis 5 mit ihrem Quadrat aus
#include <stdio.h>
int main(void) {
for (int i = 1; i <= 5; i++) {
printf("%d hoch 2 = %d\n", i, i*i);
}
return 0;
}
1 hoch 2 = 1
2 hoch 2 = 4
3 hoch 2 = 9
4 hoch 2 = 16
5 hoch 2 = 25
i <= 5 geschrieben (kleiner-gleich), damit die 5 dabei ist. Mit i < 5 hätten wir nur 1 bis 4.
âSolange das wahr ist â mach weiter." Nutzen wir, wenn wir vorher nicht wissen, wie oft.
// Zähle Eingaben, bis der Benutzer 0 eingibt
int zahl = 1;
int anzahl = 0;
while (zahl != 0) {
printf("Gib eine Zahl (0 = Stop): ");
scanf("%d", &zahl);
if (zahl != 0) anzahl++;
}
printf("Du hast %d Zahlen eingegeben\n", anzahl);
zahl = 1 vor der Schleife, damit die Bedingung beim ersten Check schon definiert ist. Sonst wäre zahl uninitialisiert â Zufallswert â unvorhersagbares Verhalten.
Sehr einfacher Ablauf: erst prĂźfen, dann ausfĂźhren.
while (5 > 10) macht nichts.
Wie while â aber der Body läuft mindestens einmal. Die Bedingung wird erst am Ende geprĂźft.
// Frag nach einer Zahl zwischen 1 und 10 â bis sie passt
int zahl;
do {
printf("Gib eine Zahl zwischen 1 und 10: ");
scanf("%d", &zahl);
} while (zahl < 1 || zahl > 10);
printf("Danke: %d\n", zahl);
while (...) am Ende von do-while steht ein Semikolon. Bei ânormalem" while nicht.
Anderer Pfad: erst tun, dann fragen.
| Schleife | Bedingung geprßft | Mind. Durchläufe | Typische Nutzung |
|---|---|---|---|
| for | vor Body | 0 | Zähler-basiert: âmache n-mal" (Arrays durchlaufen, von 1 bis 100 zählen) |
| while | vor Body | 0 | Daten-basiert: âsolange noch Eingabe da ist", âsolange Datei nicht zu Ende" |
| do-while | nach Body | 1 | Eingabe-Validierung: âfrage mindestens einmal â wiederhole bis OK" |
for. while ist die zweithäufigste. do-while ist selten â meist fĂźr Eingabe-Kontrolle.
for (int i=0; i<10; i++) {
if (i == 5) break;
printf("%d ", i);
}
// Ausgabe: 0 1 2 3 4
Verlässt die Schleife komplett. Was nach der Schleife steht, läuft normal weiter.
for (int i=0; i<6; i++) {
if (i % 2 == 0) continue;
printf("%d ", i);
}
// Ausgabe: 1 3 5
Springt zum nächsten Durchgang. Die Schleife läuft weiter â nur dieser Body wird abgebrochen.
break/continue machen Code schwerer zu lesen. Wenn mĂśglich, formuliere die Bedingung direkt um.
Eine Schleife in einer Schleife. Die innere läuft pro äuĂeren Durchgang komplett durch.
for (int i = 1; i <= 3; i++) { // äuĂere Schleife
for (int j = 1; j <= 3; j++) { // innere Schleife
printf("(%d,%d) ", i, j);
}
printf("\n");
}
(1,1) (1,2) (1,3)
(2,1) (2,2) (2,3)
(3,1) (3,2) (3,3)
Mit zwei verschachtelten Schleifen lassen sich elegante Muster erzeugen â z.B. ein Dreieck:
for (int i=1; i<=5; i++) {
for (int j=1; j<=i; j++) {
printf("* ");
}
printf("\n");
}
*
* *
* * *
* * * *
* * * * *
j <= i). Daher wächst jede Zeile um ein Sternchen.
Klassischer Bug: die Bedingung wird nie falsch. Programm hängt â Ctrl+C drĂźcken.
int i = 0;
while (i < 10) {
printf("Hilfe!\n");
// i wird nie hochgezählt!
}
â druckt âHilfe!" fĂźr immer.
for (int i=10; i > 0; i++) {
// i++ statt i--
printf("%d ", i);
}
â i wird immer grĂśĂer, nie kleiner als 0.
âHätte ich nicht 5 ausgeben sollen?" â falsche Bedingungs-Grenze.
| Code | Was du wolltest | Was du bekommst | Fix |
|---|---|---|---|
for (i=0; i<5; i++) | 1 bis 5 | 0, 1, 2, 3, 4 | for (i=1; i<=5; i++) |
for (i=1; i<5; i++) | 1 bis 5 | 1, 2, 3, 4 (5 fehlt!) | i<=5 |
for (i=0; i<=5; i++) | 5 StĂźck | 6 StĂźck (0â5) | i<5 |
for (int i = 0; i < n; i++).
// Berechne 1 + 2 + ⌠+ 100
int summe = 0;
for (int i = 1; i <= 100; i++) {
summe = summe + i; // gleichwertig: summe += i;
}
printf("Summe: %d\n", summe); // 5050
summe wird in jedem Durchgang verändert â nicht nur der Zähler i. Das ist das Muster fĂźr âetwas mit jedem Element machen".
summe muss vor der Schleife auf 0 gesetzt werden â sonst zählt der erste Durchgang einen Zufallswert dazu.
// Zähle rĂźckwärts von 10 bis 1, dann âLiftoff!"
for (int i = 10; i >= 1; i--) {
printf("%d⌠", i);
}
printf("đ Liftoff!\n");
10⌠9⌠8⌠7⌠6⌠5⌠4⌠3⌠2⌠1⌠đ Liftoff!
>=), Schritt negativ (i--).
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
printf("*");
}
}
for fßr zähler-basierte Wiederholungen, while fßr bedingungs-basierte, do-while wenn der Body mindestens einmal laufen muss.break verlässt die Schleife, continue ßberspringt einen Durchgang.Schleifen-Praxis in C: kleine Programme mit for, while und do-while bauen. Plus eure Git/GitHub-Setup mit SSH.
In Vorlesung 7 kombinieren wir Schleifen mit der nächsten groĂen Idee:
Fragen?
Prof. Dr. Alexandra Mikityuk
HTW Berlin ¡ Bßro Raum 308
Tel +49 30 5019-2664
Nächste Woche: Arrays & Strings