Informatik

Funktionen programmieren: Aufbau und Anwendung

Funktionen programmieren: Aufbau und Anwendung
Funktionen programmieren: Aufbau und Anwendung
Für Quiz, Lückentext, Lernkarten und Fortschritt ist JavaScript nötig. Alle Inhalte und Lösungen bleiben direkt lesbar.

Eine Funktion bündelt eine klar umrissene Aufgabe unter einem Namen. Du kannst ihr Werte übergeben und ihr Ergebnis an anderer Stelle weiterverwenden. So zerlegst du größere Probleme in überschaubare, wiederverwendbare Teile.

Auf dieser Seite planst du Funktionsschnittstellen, setzt sie in Python um und prüfst, ob Ein- und Ausgaben zusammenpassen.

Deine Lernziele

Hake ab, was du schon kannst — und komm am Ende hierher zurück!

Was macht eine Funktion aus?

Stell dir vor, dein Programm muss an mehreren Stellen einen Gesamtpreis berechnen. Statt die Rechnung jedes Mal neu zu schreiben, legst du sie einmal als Funktion fest.

Definition

Funktion

Eine Funktion ist ein benannter, wiederverwendbarer Programmteil. Parameter sind Platzhalter für Eingaben. Beim Aufruf eingesetzte Werte heißen Argumente. Mit return kann die Funktion einen Wert an die aufrufende Stelle zurückgeben.

In Python sieht eine einfache Definition zeilenweise so aus:

  1. def berechne_gesamtpreis(menge, einzelpreis):
  2. return menge * einzelpreis

Die erste Zeile bildet den Funktionskopf. Er enthält das Schlüsselwort def, den Namen und die Parameter. Der eingerückte Funktionsrumpf beschreibt die Berechnung.

Die Definition führt die Rechnung noch nicht aus. Erst berechne_gesamtpreis(4, 12) ist ein Aufruf. Dabei erhält menge den Wert 4 und einzelpreis den Wert 12. Die Funktion gibt 48 zurück.

Merke

Die Definition legt fest, was geschehen soll. Der Aufruf führt die Funktion mit konkreten Argumenten aus.

Teste dich
Frage 1 von 2LeichtWelche Zeile ruft eine bereits definierte Funktion auf?
Lösung: berechne_gesamtpreis(4, 12) — Beim Aufruf steht der Funktionsname mit konkreten Argumenten in Klammern.
Frage 2 von 2MittelWas bedeutet menge im Funktionskopf?
Lösung: menge ist ein Parameter und damit ein Platzhalter für eine Eingabe. — Parameter beschreiben die Eingaben einer Funktion. Konkrete Werte werden erst beim Aufruf eingesetzt.
Wie planst du eine klare Schnittstelle?

Bevor du programmierst, solltest du die Schnittstelle der Funktion festlegen. Sie beschreibt, wie anderer Programmcode die Funktion benutzt.

Definition

Funktionsschnittstelle

Zu einer klaren Funktionsschnittstelle gehören:

  • ein Name, der die Aufgabe beschreibt;
  • die benötigten Parameter;
  • der zurückgegebene Wert;
  • eine Vorbedingung, falls nicht jede Eingabe erlaubt oder sinnvoll ist.

Für die Gesamtpreisfunktion passt folgende Planung:

BestandteilFestlegung
Nameberechne_gesamtpreis
Parametermenge, einzelpreis
RückgabewertGesamtpreis
VorbedingungMenge und Einzelpreis sind nicht negativ.

Eine Vorbedingung sagt, was vor dem Aufruf gelten muss. Sie verhindert Missverständnisse über den erlaubten Eingabebereich. In umfangreicheren Programmen kann eine Funktion solche Bedingungen zusätzlich prüfen.

Der Rückgabewert lässt sich direkt speichern oder weiterverarbeiten:

  1. preis = berechne_gesamtpreis(4, 12)
  2. endpreis = preis - 12

Nach dem ersten Schritt enthält preis den Wert 48; nach dem zweiten enthält endpreis den Wert 36.

Teste dich
Frage 1 von 1MittelEine Funktion soll aus Länge und Breite den Flächeninhalt eines Rechtecks berechnen. Welche Schnittstelle ist am klarsten?
Lösung: Name berechne_flaeche, Parameter laenge und breite, Rückgabe des Flächeninhalts — Name, Parameter und Rückgabewert sollten gemeinsam genau die geplante Berechnung beschreiben.
Wie zerlegst du ein größeres Problem?

Angenommen, ein Programm soll den Endpreis einer Ticketbestellung mit Rabatt berechnen. Die Gesamtaufgabe lässt sich in drei Teilprobleme zerlegen:

  1. Gesamtpreis vor dem Rabatt berechnen.
  2. Rabattbetrag berechnen.
  3. Rabattbetrag vom Gesamtpreis abziehen.

Jedes Teilproblem erhält eine eigene Funktion:

  • berechne_gesamtpreis(menge, einzelpreis) liefert menge * einzelpreis.
  • berechne_rabatt(summe, prozent) liefert summe * prozent / 100.
  • berechne_endpreis(summe, rabatt) liefert summe - rabatt.
Beispiel

Vier Tickets kosten jeweils 12 Euro. Der Rabatt beträgt 25 Prozent.

  1. berechne_gesamtpreis(4, 12) ergibt 48 Euro.
  2. berechne_rabatt(48, 25) ergibt 12 Euro.
  3. berechne_endpreis(48, 12) ergibt 36 Euro.

Der entscheidende Gedanke ist die Verbindung der Ausgaben und Eingaben: Der Rückgabewert einer Funktion wird zum Argument der nächsten Funktion.

Die Gesamtpreisfunktion ist nicht auf diesen einen Fall festgelegt. berechne_gesamtpreis(3, 12) liefert 36 Euro, während berechne_gesamtpreis(2, 15) 30 Euro liefert. Derselbe Programmteil arbeitet in unterschiedlichen Aufrufkontexten, weil die veränderlichen Werte als Argumente übergeben werden.

Merke

Eine sinnvolle Zerlegung gibt jedem Teilproblem eine klare Aufgabe und verbindet die Funktionen über ausdrücklich benannte Ein- und Ausgaben.

Teste dich
Frage 1 von 2MittelWelche Reihenfolge verbindet die drei Funktionen korrekt?
Lösung: Erst Gesamtpreis, dann Rabattbetrag, dann Endpreis berechnen — Ein Teilproblem muss seinen Rückgabewert bereitstellen, bevor die nächste Funktion ihn als Argument verwenden kann.
Frage 2 von 2SchwerWarum ist berechne_gesamtpreis(menge, einzelpreis) besser wiederverwendbar als eine Funktion, in der die Werte 4 und 12 fest eingebaut sind?
Lösung: Die Parameter erlauben verschiedene Mengen und Einzelpreise. — Veränderliche Angaben gehören als Parameter in die Schnittstelle. Dadurch bleibt die Berechnung gleich, während die Argumente wechseln.
Rückgabe, Ausgabe und Nebeneffekt unterscheiden

return und print erfüllen verschiedene Aufgaben:

  • return gibt einen Wert an den aufrufenden Programmteil zurück.
  • print erzeugt eine sichtbare Ausgabe, liefert aber nicht automatisch den angezeigten Wert zur Weiterverarbeitung.

Eine Python-Funktion ohne ausdrückliches return gibt den besonderen Wert None zurück. Wenn du eine Zahl erwartest und stattdessen None erhältst, hast du möglicherweise return vergessen.

Beispiel

Diese Funktion zeigt nur Text an:

  1. def zeige_preis(preis):
  2. print(preis)

Diese Funktion liefert dagegen einen berechneten Wert:

  1. def verdopple(wert):
  2. return 2 * wert

Das Ergebnis von verdopple(15) ist 30 und kann gespeichert oder als Argument weitergereicht werden.

In manchen Sprachen bezeichnet man ein Unterprogramm ohne Rückgabewert als Prozedur. Die Bezeichnungen unterscheiden sich jedoch zwischen Programmiersprachen. Python nennt auch Definitionen ohne ausdrückliches return Funktionen.

Eine Veränderung, die außerhalb der Funktion beobachtbar ist, heißt Nebeneffekt. Beispiele sind eine Ausgabe oder die Veränderung einer globalen Variablen. Globale Variablen sind außerhalb der Funktion definiert und können dadurch versteckte Abhängigkeiten schaffen.

Definition

Reine Funktion

Eine reine Funktion liefert für dieselben Eingaben stets dasselbe beobachtbare Ergebnis und verursacht keine von außen beobachtbaren Zustandsänderungen. Ihr Aufruf kann deshalb gedanklich durch seinen Rückgabewert ersetzt werden.

Nicht jede Funktion in jedem Programm muss rein sein. Klare Parameter und Rückgabewerte machen Abhängigkeiten aber sichtbar und erleichtern das Nachvollziehen und Testen.

Teste dich
Frage 1 von 2LeichtWas passiert in Python, wenn eine Funktion ohne return endet?
Lösung: Sie gibt None zurück. — Python verwendet None, wenn kein anderer Rückgabewert festgelegt wurde.
Frage 2 von 2MittelWelche Funktion verhält sich bei gleichen Argumenten am ehesten wie eine reine Funktion?
Lösung: Eine Funktion, die ausschließlich ihre beiden Parameter addiert und die Summe zurückgibt — Eine reine Funktion hängt für ihr Ergebnis nur von ihren sichtbaren Eingaben ab und verändert keinen beobachtbaren Zustand.
Wie werden Funktionen selbst zu Werten?

In Python und in funktionalem Programmierstil können Funktionen ähnlich wie andere Werte gespeichert oder übergeben werden.

Bei operation = verdopple fehlen die Aufrufklammern absichtlich. Die Variable operation verweist dadurch auf die Funktion selbst. operation = verdopple(15) würde dagegen sofort den Rückgabewert 30 speichern.

Eine Funktion kann auch eine andere Funktion als Parameter erhalten:

  1. def wende_an(funktion, wert):
  2. return funktion(wert)

Der Aufruf wende_an(verdopple, 15) übergibt verdopple ohne Aufrufklammern. Erst innerhalb von wende_an wird sie mit dem Wert 15 aufgerufen. Das Ergebnis ist 30.

Definition

Funktion höherer Ordnung

Eine Funktion höherer Ordnung erhält mindestens eine Funktion als Argument oder gibt eine Funktion zurück. Dadurch kann ein allgemeiner Ablauf mit unterschiedlichem Verhalten kombiniert werden.

Auch map folgt dieser Idee: Die übergebene Funktion wird auf jedes Element einer Liste angewendet. Das Verfahren bleibt gleich, während die konkrete Funktion wechseln kann.

Teste dich
Frage 1 von 2MittelWelche Zuweisung speichert die Funktion selbst statt ihres Ergebnisses?
Lösung: operation = verdopple — Ohne Aufrufklammern wird die Funktion als Wert verwendet.
Frage 2 von 2SchwerWelcher Vorteil entsteht, wenn eine Funktion eine andere Funktion als Argument erhält?
Lösung: Ein allgemeiner Ablauf kann mit verschiedenen Berechnungen wiederverwendet werden. — Funktionen höherer Ordnung trennen den allgemeinen Ablauf von der jeweils eingesetzten Operation.
Eine Funktion systematisch entwerfen

Nutze beim Entwerfen diese Reihenfolge:

  1. Formuliere das Teilproblem in einem Satz.
  2. Wähle einen Namen, der dieses Teilproblem beschreibt.
  3. Bestimme alle nötigen Eingaben als Parameter.
  4. Lege Rückgabewert und mögliche Vorbedingungen fest.
  5. Implementiere nur die geplante Aufgabe.
  6. Rufe die Funktion mit mindestens zwei passenden Eingabesätzen auf.
  7. Prüfe Rückgabewert, Einheit und Bedeutung im Sachzusammenhang.
Beispiel

Aufgabe: Entwirf eine Funktion, die einen Preis nach Abzug eines Rabattbetrags liefert. Verwende sie einmal für 48 Euro mit 12 Euro Rabatt und einmal für 36 Euro mit 6 Euro Rabatt.

Lösung:

  • Teilproblem: Ziehe den Rabattbetrag vom bisherigen Preis ab.
  • Name: berechne_endpreis
  • Parameter: summe, rabatt
  • Rückgabewert: Preis nach dem Abzug
  • Vorbedingung: Beide Beträge sind nicht negativ; der Rabatt ist nicht größer als die Summe.

Implementierung:

  1. def berechne_endpreis(summe, rabatt):
  2. return summe - rabatt

Die Aufrufe liefern berechne_endpreis(48, 12) = 36 und berechne_endpreis(36, 6) = 30.

Prüfe nicht nur, ob der Code ausgeführt wird. Frage auch, ob der Rückgabewert im jeweiligen Zusammenhang sinnvoll ist. Ein negativer Endpreis würde beispielsweise die festgelegte Vorbedingung verletzen.

Teste dich
Frage 1 von 1SchwerEine Funktion benötigt plötzlich eine globale Variable, die nicht in ihrer Schnittstelle steht. Was ist der beste erste Prüfschritt?
Lösung: Prüfen, ob die globale Abhängigkeit als Parameter sichtbar gemacht werden kann — Wenn eine benötigte Eingabe als Parameter erscheint, erkennen Aufrufende die Abhängigkeit direkt und können verschiedene Werte einsetzen.
Karteikasten
Karteikasten

Überlege zuerst selbst und drehe die Karte anschließend zum Prüfen um.

Alles auf einen Blick
Mindmap
  • Funktionen programmieren
    • Aufbau: Kopf, Parameter und eingerückter Rumpf
    • Verwendung: Definition festlegen und anschließend aufrufen
    • Schnittstelle: Name, Eingaben, Rückgabewert und Vorbedingung
    • Zerlegung: Gesamtproblem in verbundene Teilprobleme aufteilen
    • Rückgabe: Ergebnisse mit `return` weiterverwendbar machen
    • Nachvollziehbarkeit: versteckte globale Abhängigkeiten vermeiden
    • Erweiterung: Funktionen als Werte übergeben
Abschluss-Check
Teste dich
Frage 1 von 3LeichtWas unterscheidet eine Funktionsdefinition von einem Funktionsaufruf?
Lösung: Die Definition beschreibt das Verhalten; der Aufruf führt es mit konkreten Argumenten aus. — Definition und Aufruf sind zwei getrennte Schritte: erst festlegen, dann verwenden.
Frage 2 von 3MittelEine Berechnung wird an drei Stellen mit unterschiedlichen Zahlen benötigt. Welche Lösung ist am sinnvollsten?
Lösung: Eine Funktion mit Parametern für die veränderlichen Zahlen definieren und mehrfach aufrufen — Parameter machen die wechselnden Eingaben sichtbar, während die Berechnung zentral gepflegt wird.
Frage 3 von 3SchwerEin Bestellprogramm soll Gesamtpreis, Rabattbetrag und Endpreis berechnen. Welche Zerlegung besitzt die klarsten Schnittstellen?
Lösung: Drei Funktionen, deren Rückgabewerte als Argumente an die jeweils nächste Berechnung weitergegeben werden — Klare Parameter und Rückgabewerte verbinden die Teilprobleme nachvollziehbar und machen jede Berechnung einzeln testbar.

Du kannst eine Funktion sicher einsetzen, wenn du ihre Aufgabe, Eingaben, Bedingungen und Rückgabe klar benennen kannst. Bei größeren Problemen wiederholst du diesen Entwurf für jedes Teilproblem und verbindest die Funktionen über ihre sichtbaren Schnittstellen.

Passend dazu