Programmieren in C

Programmsteuerung

Im Kapitel C Grundlagen wurden die Grundlagen der Programmiersprache C vorgestellt.
Dazu gehörten der Aufbau eines Programms, die Funktion main(), die Verwendung von Variablen und Datentypen sowie erste Ein- und Ausgaben.

In diesem Kapitel gehen wir einen entscheidenden Schritt weiter: Wir betrachten die eigentliche Programmsteuerung.
Ein Programm besteht nicht nur aus einer linearen Abfolge von Anweisungen, sondern muss in der Lage sein:

Diese Kontrollstrukturen sind die zentralen Werkzeuge, um komplexe Probleme in C zu lösen. Sie erlauben es, den Programmfluss gezielt zu steuern, statt Anweisungen starr und einmalig auszuführen.

Das Kapitel vermittelt deshalb:

Damit wird die Grundlage geschaffen, um Programme nicht nur korrekt, sondern auch dynamisch, flexibel und strukturiert zu entwickeln.

Bedingte Verzweigungen mit if

Programme sollen nicht nur Anweisungen nacheinander abarbeiten, sondern auch Entscheidungen treffen können.
In C geschieht das mit der if-Anweisung.
Sie prüft eine Bedingung (logischer Ausdruck) und entscheidet, ob ein Anweisungsblock ausgeführt wird oder nicht.

Syntax:

if(Bedingung) {
    // Anweisungen
}

Bedingung: ein logischer Ausdruck (liefert 0 = falsch oder ≠0 = wahr).
Anweisungen: Die Anweisungen werden ausgeführt, wenn die Bedingung wahr ist.

Beispiel für eine einfache if Bedingung:

#include <stdio.h>

int main() {
    int zahl = 10;

    if (zahl > 5) {
        printf("Die Zahl ist größer als 5.\n");
    }

    return 0;
}

Bedingte Verzweigungen mit if else

Mit else kann ein alternativer Anweisungsblock ausgeführt werden, falls die Bedingung nicht erfüllt ist.

Syntax:

if(Bedingung) {
    // Anweisungen true
}

else {
    // Anweisungen false
}

Bedingung: ein logischer Ausdruck (liefert 0 = falsch oder ≠0 = wahr).
Anweisungen true: Die Anweisungen werden ausgeführt, wenn die Bedingung wahr ist.
Anweisungen false: Die Anweisungen werden ausgeführt, wenn die Bedingung falsch ist.

Beispiel für if else:

int alter = 16;

if (alter >= 18) {
    printf("Volljährig.\n");
} else {
    printf("Noch nicht volljährig.\n");
}

Mehrfache Verzweigungen mit else if

Mit else if lassen sich mehrere Alternativen prüfen.

Beispiel für Mehrfachverzweigungen:

int note = 2;

if (note == 1) {
    printf("Sehr gut\n");
} else if (note == 2) {
    printf("Gut\n");
} else if (note == 3) {
    printf("Befriedigend\n");
} else {
    printf("Ausreichend oder schlechter\n");
}

Verschachtelte if-Anweisungen

if-Anweisungen können innerhalb anderer if- oder else-Blöcke stehen → verschachtelte Verzweigungen.

Beispiel für verschachtelte Verzweigungen:

int zahl = 12;

if (zahl > 0) {
    if (zahl % 2 == 0) {
        printf("Positive gerade Zahl\n");
    } else {
        printf("Positive ungerade Zahl\n");
    }
} else {
    printf("Zahl ist nicht positiv\n");
}

Bedingungen logisch kombinieren

Mit logischen Operatoren können mehrere Bedingungen logisch verknüpft werden:

Beispiel für logische Verknüpfung von Bedingungen:

int alter = 20;
char ausweis = 'J';

if (alter >= 18 && ausweis == 'J') {
    printf("Zutritt erlaubt.\n");
} else {
    printf("Kein Zutritt.\n");
}

Schleifen in C

In vielen Situationen muss ein Programm wiederholt dieselben Anweisungen ausführen.

Beispiel: Wir möchten für die Funktion f(x)=x2 die Funktionswerte für x von 1 bis 10 berechnen und ausgeben.

Ohne Schleifen müssten wir jede Berechnung einzeln programmieren – unpraktisch und fehleranfällig.

Mit Schleifen (loops) können wir solche Wiederholungen elegant und automatisch lösen.

C kennt verschiedene Typen von Schleifen.

Welcher Typ am besten eingesetzt wird hängt von der Aufgabe ab.

Schleifen lassen sich auch verschachteln, das heißt: Innerhalb einer Schleife können weitere Schleifen stehen.
Auf diese Weise lassen sich mehrdimensionale Abläufe, wie zum Beispiel Tabellen oder Matrizen, elegant darstellen.

Zusätzlich kann der Ablauf einer Schleife gezielt gesteuert werden:

Die while-Schleife

Die while-Schleife gehört zu den wichtigsten Kontrollstrukturen in C.
Sie wiederholt einen Anweisungsblock so lange, wie eine bestimmte Bedingung wahr (true) ist.
Man spricht von einer kopfgesteuerten Schleife, da die Bedingung bereits vor dem ersten Durchlauf geprüft wird.

Syntax:

while(Bedingung) {
    // Anweisungen
}

Bedingung: ein logischer Ausdruck (liefert 0 = falsch oder ≠0 = wahr).
Anweisungen: Der Schleifenrumpf besteht aus Anweisungen, die wiederholt werden so lange die Bedingung wahr ist.

Beispiel für eine Zählschleife:

#include <stdio.h>

int main() {
    int i = 1;

    while (i <= 5) {
        printf("Wert: %d\n", i);
        i++;    // Zähler erhöhen
    }

    return 0;
}

Erklärung:

  • Startwert: i = 1
  • Bedingung: i ≤ 5
  • Solange die Bedingung wahr ist, wird der Schleifenrumpf ausgeführt.
  • Nach jedem Durchlauf wird i um 1 erhöht.

Beispiel: Schleifensteuerung mit break und continue

#include <stdio.h>

int main() {
    int i = 0;

    while (i < 10) {
        i++;

        if (i == 5) {
            continue;   // überspringt die Ausgabe für i = 5
        }

        if (i == 8) {
            break;      // Schleife wird bei i = 8 beendet
        }

        printf("i = %d\n", i);
    }

    return 0;
}

Bildschirmausgabe:

i = 1
i = 2
i = 3
i = 4
i = 6
i = 7

Dauerschleifen mit while

Ein Sonderfall sind Dauerschleifen, bei denen die Bedingung einer while-Schleife dauerhaft wahr ist (while(1){...).

Der Ausstieg erfolgt dann ausschließlich durch eine Abbruchanweisung wie break im Schleifenrumpf.
Solche Konstruktionen bergen die Gefahr einer unerwünschten Endlosschleife, wenn der vorgesehene Abbruch nicht eintritt.

Achtung! Bei Dauerschleifen muss immer sichergestellt werden, dass die Schleife zuverlässig beendet werden kann.

Dies kann durch eine eindeutige Bedingung oder durch gezielten Einsatz von break erreicht werden.

Beispiel für eine Dauerschleife:

#include <stdio.h>

int main() {
    int i = 0;
    while (1) {
        i++;  // äquivalent zu  i=i+1
        if (i == 10) {
            break;      // Schleife wird bei i = 10 beendet
        }
        printf("i = %d\n", i);
    }
    return 0;
}

Zählschleifen mit for

Viele Aufgaben erfordern eine feste Anzahl von Wiederholungen.

Für solche Fälle eignet sich die for-Schleife.

Syntax:

for(Startwert; Bedingung; Veränderung) {
    // Anweisungen
}

Startwert: Initialisierung des Zählers (z. B. int i = 0;)
Bedingung: ein logischer Ausdruck (liefert 0 = falsch oder ≠0 = wahr).
Veränderung: ergibt wie der Zähler nach jedem Durchlauf verändert wird (z. B. i++)
Anweisungen: Der Schleifenrumpf besteht aus Anweisungen, die wiederholt werden so lange die Bedingung wahr ist.

Für mehrdimensionales Zählen werden for-Schleifen häufig verschachtelt.

Beispiel für eine for-Schleife:

#include <stdio.h>

int main() {

    for (int i = 1; i<=10; i++) {
        printf("Wert: %d\n", i);
    }

    return 0;
}

Benutzereingaben mit scanf()

Damit Programme interaktiv werden, müssen sie Eingaben vom Benutzer entgegennehmen können.

In der Programmiersprache C geschieht das mit der Funktion scanf() aus der Bibliothek stdio.h.

Syntax:

scanf("Formatzeichen", Adresse)

Formatzeichen: Legt den Datentyp der Eingabe fest.
Adresse: Die Adresse der Variablen, an die der Inhalt übergeben werden soll.

Wichtige Formatzeichen sind:

Datentyp

Formatzeichen

Beispiel

int (Ganzzahl)

%d

scanf("%d", &zahl);

float (Fließkommazahl)

%f

scanf("%f", &wert);

char (einzelnes Zeichen)

%c

scanf("%c", &zeichen);

string (Text)

%s

scanf("%s", name);

Der Adressoperator &

Bei der Eingabe mit scanf() muss der eingegebene Wert in einer Variable gespeichert werden. Damit scanf() weiß, wo im Speicher dieser Wert abgelegt werden soll, braucht es die Adresse dieser Variable.

Dafür wird in C der Adressoperator & verwendet.

Beispiel:

int zahl = 0;
scanf("%d", &zahl);

&zahl übergibt die Speicheradresse der Variablen zahl an scanf().
Würde man nur zahl (ohne &) schreiben, führt das zu einem Fehler.

Bei Arrays (z. B. Zeichenketten) ist der Name des Arrays die Adresse des ersten Elements. Hier darf kein & verwendet werden

Beispiel:

char Text[25];
scanf("%s", Text);

Eingabe mehrerer Variablen mit scanf()

Mit scanf() können auch mehrere Variablen vom Benutzer abgefragt werden.
Diese müssen durch Leerzeichen getrennt werden.

Beispiel:

int a;
float b;
scanf("%d %f", &a, &b);