Zusammenfassung
Diese Lektion eröffnet die fünfte Einheit des Kurses, die den Funktionen gewidmet ist. Sie erklärt, wozu die Einheit dient: zu lehren, wie man ein Problem in benannte Teile zerlegt, jeden mit einer Schnittstelle und einem Vertrag, und wie man bestimmte Probleme löst, indem man sie auf eine kleinere Instanz ihrer selbst zurückführt, durch Rekursion; sie stellt ihre vier Lektionen vor und den Faden, der sie verbindet; sie erinnert daran, was die Einheit voraussetzt, vor allem die Schleifen der Einheit 4 und ihre Invarianten; sie formuliert das Problem, das die Einheit löst, das eines Programms, das dieselbe kopierte Berechnung wiederholt und wegen eines Versehens beim Kopieren falsch antwortet, ohne dass der Compiler etwas sagt; sie nimmt den Vertrag (die Vorbedingung und die Nachbedingung) als die Form vorweg, in der die Einheit jeden Teil spezifizieren wird; und sie zeigt, wohin sie führt, in den folgenden Einheiten und im Kurs Programmieren in C++ II.
Lernziele
- Die Abfolge der Inhalte der Einheit beschreiben und erklären, was jede Lektion zur nächsten beiträgt.
- Die Algorithmen der Einheit 4 (die Ablaufverfolgung einer Schleife, ihre Invariante und ihre Variante) in Erinnerung rufen und sie bei Bedarf wiederholen.
- An einem Beispiel die Idee des Vertrags vorwegnehmen: was ein Teil des Programms von dem verlangt, der ihn benutzt, und was er ihm im Gegenzug garantiert.
- Erkennen, was man am Ende der Einheit können soll, und es von dem unterscheiden, was in den folgenden Einheiten gelernt wird.
Eingangstest
Bevor man die Einheit durcharbeitet, lohnt es sich, den Ausgangspunkt zu bestimmen. Dieser Test ist eine Selbstüberprüfung: Er wird nicht benotet, und sein einziger Zweck ist es, das Lernen zu leiten. Die ersten fünf Fragen prüfen, was die Einheit voraussetzt: die Ablaufverfolgung einer Schleife, ihre Invariante, die Vorbedingung einer Spezifikation, das Kopieren eines Wertes bei der Initialisierung und die Suche nach einer Berechnung mit eigenen Eingaben und Ausgaben innerhalb eines Programms der Einheit 4. Die fünf folgenden behandeln in der Reihenfolge der Lektionen die zentralen Ideen der Einheit: den Aufrufstapel, die Übergabe eines Arguments, die Trennung von Berechnung und Darstellung, die rekursive Definition der Fakultät und die Ausführung einer Funktion, die sich selbst aufruft. Niemand muss sie schon richtig beantworten, und bei einigen von ihnen ist „Das weiß ich noch nicht“ eine ehrliche Antwort: Jede Antwort, ob richtig oder nicht, erklärt den Punkt und nennt die Lektion, die ihn behandelt. Dieselben Fertigkeiten werden am Ende erneut gemessen, in der Synthese-Lektion.
Miss vor Beginn der Einheit deinen Ausgangspunkt. Es ist eine kurze Selbsteinschätzung: Sie wird nicht benotet, und das Ergebnis wird nur in deinem Browser gespeichert.
Frage 1Aus früheren EinheitenWas schreibt
int n{305}; int c{1}; while (n >= 10) { n = n / 10; ++c; } std::println("{}", c);?Zählt die Durchläufe und vergisst, dasscbei 1 beginnt.Macht einen Durchlauf zu viel: Bei ist die Bedingungn >= 10bereits falsch.Verwechselt den Zähler mit dem Wert vonnnach dem ersten Durchlauf.Die Ablaufverfolgung ergibt und : Der Rumpf wird zweimal ausgeführt, und bei ist die Bedingung nicht mehr erfüllt. Die Schleife zählt die Ziffern einer natürlichen Zahl; die Lektion Funktionen schließt sie in eine Funktion mit Namen und Vertrag ein, und die Lektion Rekursion schreibt sie ohne Schleife.Wiederholen: Schleifen
Frage 2Aus früheren EinheitenIn der Schleife
int total{0}; int k{1}; while (k <= n) { total += k; ++k; }mit : Welche Beziehung gilt jedes Mal, wenn die Bedingung ausgewertet wird?Gilt mitten im Durchlauf, nach dem Addieren und vor dem Erhöhen, aber nicht, wenn die Bedingung ausgewertet wird.Gilt erst am Ende: Das ist die Nachbedingung, nicht die Invariante.Das ist die Bedingung der Schleife, und sie ist gerade beim Verlassen falsch; eine Invariante gilt auch dann.Sie gilt zu Beginn, mit der leeren Summe und ; und wenn sie vor einem Durchlauf gilt, gilt sie auch danach, denn der Durchlauf addiert und erhöht es anschließend. Beim Verlassen gilt , und die Invariante liefert die Summe von 1 bis . Die Lektion Rekursion begründet ihre Funktionen mit derselben Argumentation durch Induktion.Wiederholen: Korrekte Schleifen entwerfen
Frage 3Aus früheren EinheitenDie Spezifikation der Division lautet: „Gegeben ganze Zahlen und , bestimme und mit und .“ Was ist ihre Vorbedingung?
Verwechselt die Vorbedingung mit der Nachbedingung: Das ist es, was das Ergebnis erfüllt, nicht, was von den Daten verlangt wird.Das ist eine Bedingung an die Ausgabe, nicht an die Eingabe.Bei gibt es kein mit : Das Problem hat keine Lösung, und die Vorbedingung schließt es aus.Die Vorbedingung ist das, was von den Daten verlangt wird, damit das Problem eine Lösung hat; die Nachbedingung das, was das Ergebnis erfüllt. Die Einheit macht aus diesem Paar den Vertrag jeder Funktion: Die Vorbedingung verpflichtet den Aufrufer, die Nachbedingung die Funktion.Wiederholen: Vom Problem zum Algorithmus
Frage 4Aus früheren EinheitenWelchen Wert hat nach
int a{3}; int b{a}; b = 7;die Variablea?Glaubt, dassbundafür immer verbunden bleiben; die Initialisierung kopiert den Wert, nicht die Zelle.Verwechselt die Kopie mit einer nicht initialisierten Variablen:ahat 3 erhalten, und nichts hat es geändert.Die Initialisierungint b{a}kopiert in die Speicherzelle vonbden Wert, denahatte; danach sind die beiden Zellen unabhängig. Die Lektion Parameter und Gültigkeitsbereich zeigt, dass ein Parameter auf dieselbe Weise initialisiert wird, mit einer Kopie des Arguments, und lehrt die andere Möglichkeit: einen zweiten Namen für dieselbe Zelle.Wiederholen: Variablen und Speicher
Frage 5Aus früheren EinheitenDas Programm der Lektion 4.4, das die Primzahlen unter 100 schreibt, hat eine Schleife, die die Kandidaten durchläuft, und darin eine weitere, die ihre Teiler durchprobiert. Welcher Teil ist eine Berechnung mit eigenen Eingaben und Ausgaben, die man benennen sollte?
Verwechselt die Eingabe und die Ausgabe des ganzen Programms mit denen einer inneren Berechnung.Das ist eine Anweisung, keine Berechnung mit eigenem Sinn: Sie hat keine Eingabe und kein Ergebnis, das jemand benutzen wollte.Verwechselt einen Datenwert mit einer Aufgabe: Die Variable speichert das Ergebnis der Berechnung, ist aber nicht die Berechnung.Die innere Schleife hängt von nichts anderem ab als vom Kandidaten, und ihr Ergebnis ist ein Ja oder ein Nein. Ihr einen Namen zu geben erlaubt es, die äußere Schleife als ihre Spezifikation zu lesen: „Für jeden Kandidaten: Wenn er prim ist, schreibe ihn.“ Die Lektion Mit Funktionen entwerfen schreibt dieses Programm so um.Wiederholen: Numerische Algorithmen
Frage 6Ein Programm beginnt in
main;mainruft eine Funktiongauf, undgruft eine andere Funktionhauf. Welche Aufrufe laufen, währendhausgeführt wird?Glaubt, dass der Aufrufer beim Aufrufen verschwindet; er wartet vielmehr, um dort fortzufahren, wo er angehalten hat.Glaubt, dassgbeim Aufruf vonhgeendet hat; es endet, wennhihm die Kontrolle zurückgibt.Das ist eine ehrliche Antwort: Lektion 5.1 erklärt es mit einer Abbildung des Stapels.Ein Aufruf endet erst, wenn die Aufrufe geendet haben, die er gemacht hat:gwartet auf das Ergebnis vonh, undmainauf das vong. Jeder laufende Aufruf bewahrt seine Variablen in einem Stapelrahmen auf, und die Rahmen werden gestapelt; das ist der Aufrufstapel der Lektion Funktionen.Wiederholen: Funktionen
Frage 7Bei der Funktion
int f(int x) { x = x + 1; return x; }: Was schreibtint a{3}; int b{f(a)}; std::println("{} {}", a, b);?Glaubt, dass die Funktion das Argument verändert; standardmäßig erhält sie eine Kopie.Glaubt, dass die Änderung vonxnicht einmal den zurückgegebenen Wert erreicht.Glaubt, dass ein Parameter nicht verändert werden kann; er kann es, sofern er nicht alsconstdeklariert ist.Der Parameterxist eine Variable vonf, die mit einer Kopie des Arguments initialisiert wird: Die Funktion ändert die Kopie und gibt 4 zurück, undabehält seine 3. Das ist die Wertübergabe, der Standardmodus von C++.Wiederholen: Parameter und Gültigkeitsbereich
Frage 8Ein Programm liest ein Datum und soll seinen Wochentag schreiben. Welche Zerlegung trennt die Berechnung von der Darstellung?
Vermischt zwei Aufgaben: Das Berechnete lässt sich weder wiederverwenden noch mit einem erwarteten Wert vergleichen.Trennt die Aufgaben, verbindet sie aber durch eine verborgene Wirkung: Wer den Aufruf liest, sieht nicht, woher der Wert kommt.Das ist eine ehrliche Antwort: Lektion 5.3 lehrt, zu entscheiden, welche Funktionen man schreibt.So wird die Berechnung mit Zahlen getestet, ohne auf den Bildschirm zu schauen, und sie kann einem anderen Programm dienen, das das Ergebnis auf andere Weise schreibt. Lektion 5.3 nennt dieses Kriterium „eine Funktion, eine Aufgabe“.Wiederholen: Mit Funktionen entwerfen
Frage 9Welche der folgenden Definitionen definiert für jede natürliche Zahl ?
Ohne Basisfall hält die Definition nie an: verwiese auf , und so ohne Ende.Definiert richtig für , lässt aber undefiniert, dessen Wert 1 ist.Definiert durch sich selbst: Die Definition ist zirkulär und verkleinert das Problem nicht.Frage 10Bei
int f(int n) { if (n == 0) { return 0; } return n + f(n - 1); }: Was schreibtstd::println("{}", f(3));?Glaubt, dass nur ein einziger Aufruf ausgeführt wird, oder verwechselt das Argument mit dem Ergebnis.Glaubt, dass dasreturn 0des Basisfalls das Ergebnis der ganzen Kette ist; es ist nur das des letzten Aufrufs.Der Name der Funktion ist ab ihrem Kopf bekannt und kann in ihrem eigenen Rumpf verwendet werden.f(3)wartet auff(2), das auff(1)wartet, das auff(0)wartet; dieser Aufruf gibt 0 zurück, und auf dem Rückweg werden 1, 2 und 3 addiert. Die Funktion berechnet , dieselbe Summe wie die Schleife der zweiten Frage.Wiederholen: Rekursion
Inhalt wird geladen…
Abgeschlossen
Melde dich an, um deinen Fortschritt zu speichern