Grundlagen der Programmierung
Prof. Dr. Alexandra Mikityuk
HTW Berlin
Ein Algorithmus ist eine Schritt-für-Schritt-Anleitung zur Lösung eines Problems.
Wie ein Kochrezept — aber für den Computer.
Wie tauscht man zwei Variablen, ohne den ersten Wert zu verlieren?
Wann zählt man vorwärts, wann rückwärts — und warum?
Größtes Element in einem Array systematisch ermitteln.
Spiegelbild des Maximums — fast identisches Muster.
Wann zählen wir aufwärts, wann abwärts? Hängt vom Problem ab.
for (int i = 0; i < n; i++)
{
// Von Anfang bis Ende
}
for (int i = n - 1; i >= 0; i--)
{
// Von Ende bis Anfang
}
#include <stdio.h>
int main()
{
int zahlen[5] = {10, 20, 30, 40, 50};
printf("Array vorwärts:\n");
for (int i = 0; i < 5; i++)
{
printf("zahlen[%d] = %d\n", i, zahlen[i]);
}
return 0;
}
0, Bedingung i < 5, Erhöhung i++ — Standardmuster für Array-Durchlauf.
#include <stdio.h>
int main()
{
int zahlen[5] = {10, 20, 30, 40, 50};
printf("Array rückwärts:\n");
for (int i = 4; i >= 0; i--)
{
printf("zahlen[%d] = %d\n", i, zahlen[i]);
}
return 0;
}
i >= 0 (nicht i > 0) — sonst wird Element [0] übersprungen.
#include <stdio.h>
int main()
{
printf("Raketenstart!\n\n");
/* Countdown von 10 bis 1 */
for (int i = 10; i >= 1; i--)
{
printf("%d...\n", i);
}
printf("\n🚀 LIFTOFF!\n");
return 0;
}
Wie tauschen wir die Werte von zwei Variablen?
a = b; // a ist jetzt 3, aber 5 ist verloren!
b = a; // b ist auch 3 — beide sind gleich!
Problem: Der ursprüngliche Wert von a wird überschrieben, bevor wir ihn speichern können.
Drei Schritte, wie beim Umräumen von Gläsern:
#include <stdio.h>
int main()
{
int a = 5;
int b = 3;
int temp;
printf("Vorher: a = %d, b = %d\n", a, b);
/* Tauschen mit Hilfsvariable */
temp = a; // 1. Wert von a sichern
a = b; // 2. b nach a kopieren
b = temp; // 3. Gesicherten Wert nach b
printf("Nachher: a = %d, b = %d\n", a, b);
return 0;
}
Das gleiche Prinzip funktioniert auch mit Array-Elementen — nur die Namen sehen anders aus.
#include <stdio.h>
int main()
{
int zahlen[5] = {10, 20, 30, 40, 50};
int temp;
printf("Vorher: %d %d %d %d %d\n",
zahlen[0], zahlen[1], zahlen[2], zahlen[3], zahlen[4]);
/* Element 0 und Element 4 tauschen */
temp = zahlen[0];
zahlen[0] = zahlen[4];
zahlen[4] = temp;
printf("Nachher: %d %d %d %d %d\n",
zahlen[0], zahlen[1], zahlen[2], zahlen[3], zahlen[4]);
return 0;
}
Wie finden wir die größte Zahl in einem Array?
Mit dem Array {7, 3, 12, 5, 9} — was passiert in jedem Schritt?
| Schritt | Element | Vergleich | max |
|---|---|---|---|
| Start | zahlen[0] = 7 | — | 7 |
| i = 1 | zahlen[1] = 3 | 3 > 7? ❌ Nein | 7 |
| i = 2 | zahlen[2] = 12 | 12 > 7? ✅ Ja | 12 |
| i = 3 | zahlen[3] = 5 | 5 > 12? ❌ Nein | 12 |
| i = 4 | zahlen[4] = 9 | 9 > 12? ❌ Nein | 12 |
| Ende | — | — | 12 ✓ |
#include <stdio.h>
int main()
{
int zahlen[5] = {7, 3, 12, 5, 9};
int max;
/* Erstes Element als Startwert */
max = zahlen[0];
/* Alle weiteren Elemente prüfen */
for (int i = 1; i < 5; i++)
{
if (zahlen[i] > max)
{
max = zahlen[i];
}
}
printf("Das Maximum ist: %d\n", max);
return 0;
}
max = zahlen[0] — Startwerti = 1 — Schleife startet bei 1 (s. nächste Folie)if (… > max) — Vergleich + Update
i = 1?i = 0.
Der Grund: Wir setzen max = zahlen[0] vor der Schleife als Startwert. Element [0] wurde also schon „verwendet" — es wäre sinnlos, zahlen[0] > zahlen[0] zu prüfen.
max = zahlen[0]; // Index 0 ist Startwert
for (int i = 1; i < n; i++) // Ab Index 1
n − 1 Vergleiche (optimal)
max = zahlen[0];
for (int i = 0; i < n; i++) // Prüft auch [0]
n Vergleiche (1 unnötig: zahlen[0] > zahlen[0])
Fast identisch zum Maximum — nur das Vergleichszeichen ändert sich!
#include <stdio.h>
int main()
{
int zahlen[5] = {7, 3, 12, 5, 9};
int min;
/* Erstes Element als Startwert */
min = zahlen[0];
/* Alle weiteren Elemente prüfen */
for (int i = 1; i < 5; i++)
{
if (zahlen[i] < min) // Nur dieses Zeichen!
{
min = zahlen[i];
}
}
printf("Das Minimum ist: %d\n", min);
return 0;
}
> ↔ <, fertig.
Eine Schleife, zwei Ergebnisse — keine Doppelarbeit nötig.
#include <stdio.h>
int main()
{
int zahlen[5] = {7, 3, 12, 5, 9};
int min, max;
/* Beide mit erstem Element initialisieren */
min = zahlen[0];
max = zahlen[0];
for (int i = 1; i < 5; i++)
{
if (zahlen[i] < min)
min = zahlen[i];
if (zahlen[i] > max)
max = zahlen[i];
}
printf("Minimum: %d\n", min);
printf("Maximum: %d\n", max);
printf("Spannweite: %d\n", max - min);
return 0;
}
Manchmal brauchen wir nicht den Wert, sondern wo er steht — wir merken uns den Index.
#include <stdio.h>
int main()
{
int zahlen[5] = {7, 3, 12, 5, 9};
int maxPos = 0; // Position des Maximums
for (int i = 1; i < 5; i++)
{
if (zahlen[i] > zahlen[maxPos])
{
maxPos = i; // Neue Position merken
}
}
printf("Maximum %d steht an Position %d\n",
zahlen[maxPos], maxPos);
return 0;
}
zahlen[maxPos] jederzeit.
Achtung: Bei Schulnoten ist kleinere Note = besser (1 = sehr gut, 6 = ungenügend).
#include <stdio.h>
int main()
{
int noten[6] = {2, 1, 3, 2, 4, 1};
int beste = noten[0];
int schlechteste = noten[0];
for (int i = 1; i < 6; i++)
{
if (noten[i] < beste) // Kleinere Note = besser
beste = noten[i];
if (noten[i] > schlechteste) // Größere Note = schlechter
schlechteste = noten[i];
}
printf("Beste Note: %d\n", beste);
printf("Schlechteste Note: %d\n", schlechteste);
return 0;
}
switch / caseWir haben das Noten-Array — jetzt wollen wir für jede Note auch den Text ausgeben. Klassischer Fall für switch / case: ein Wert wird auf mehrere mögliche Zustände abgebildet.
#include <stdio.h>
int main()
{
int noten[6] = {2, 1, 3, 2, 4, 1};
for (int i = 0; i < 6; i++)
{
printf("Note %d: ", noten[i]);
switch (noten[i])
{
case 1: printf("sehr gut\n"); break;
case 2: printf("gut\n"); break;
case 3: printf("befriedigend\n"); break;
case 4: printf("ausreichend\n"); break;
case 5: printf("mangelhaft\n"); break;
case 6: printf("ungenügend\n"); break;
default: printf("unbekannt\n"); break;
}
}
return 0;
}
switch statt if / else if? Bei vielen festen Werten (1, 2, 3, …) liest sich switch klarer. Jedes break beendet den passenden Fall — ohne break würde der nächste Fall auch ausgeführt (Fall-Through).
switch vs. if / else if — wann was?Dieselbe Note-Klassifikation in beiden Schreibweisen — wann ihr was nehmt:
switch / caseswitch (note)
{
case 1: ...; break;
case 2: ...; break;
case 3: ...; break;
default: ...;
}
Stark, wenn:
if / else ifif (note == 1) ...;
else if (note == 2) ...;
else if (note == 3) ...;
else ...;
Stark, wenn:
note < 4)break, läuft der Code in den nächsten case weiter („Fall-Through"). Manchmal gewollt — meistens ein Bug. Immer prüfen.
switch. Bereiche oder komplexe Logik → if / else if.
Was ist der Wert von a und b nach diesem Code?
int a = 10, b = 20, temp;
temp = a;
a = b;
b = temp;
| Zeile | a | b | temp |
|---|---|---|---|
| Anfang | 10 | 20 | ? |
| temp = a | 10 | 20 | 10 |
| a = b | 20 | 20 | 10 |
| b = temp | 20 | 10 | 10 |
Was gibt dieses Programm aus?
int arr[4] = {5, 5, 5, 5};
int max = arr[0];
for (int i = 1; i < 4; i++) {
if (arr[i] > max) max = arr[i];
}
printf("%d", max);
max = arr[0] → max wird 55 > 5? → Nein, also bleibt max bei 5Welche Ausgabe erzeugt diese Schleife?
for (int i = 3; i >= 1; i--)
{
printf("%d ", i);
}
| i | i >= 1? | Ausgabe | Danach |
|---|---|---|---|
| 3 | ✅ Ja | 3 | i-- → 2 |
| 2 | ✅ Ja | 2 | i-- → 1 |
| 1 | ✅ Ja | 1 | i-- → 0 |
| 0 | ❌ Nein | — | Schleife endet |
/* Hilfsvariable + 3 Schritte */
int temp = a;
a = b;
b = temp;
temp nötigmax = arr[0];
for (i = 1; i < n; i++)
if (arr[i] > max)
max = arr[i];
min = arr[0];
for (i = 1; i < n; i++)
if (arr[i] < min)
min = arr[i];
i = 1)for (i = 0; i < n; i++)
for (i = n-1; i >= 0; i--)
i >= 0 (nicht i > 0) — sonst wird Element [0] übersprungen.