Funktionen als Argumente übergeben
Teil des Abschnitts Object Oriented Programming der C-Journey von Coddy — Lektion 36 von 61.
Eine der leistungsfähigsten Anwendungen von Funktionszeigern ist deren Übergabe als Argumente an andere Funktionen. Dies ermöglicht es Ihnen, benutzerdefiniertes Verhalten in eine Funktion einzufügen, ohne deren Code zu ändern – eine Technik, die manchmal als Callback bezeichnet wird.
Betrachten Sie eine Funktion, die eine Berechnung mit zwei Zahlen durchführt. Anstatt die Operation fest zu programmieren, können Sie einen Funktionszeiger akzeptieren, der definiert, welche Operation ausgeführt werden soll:
typedef int (*Operation)(int, int);
int compute(int a, int b, Operation op) {
return op(a, b);
}Die compute-Funktion weiß nicht, ob sie addiert, subtrahiert oder etwas ganz anderes tut. Sie ruft einfach die Funktion auf, die ihr übergeben wird:
int add(int a, int b) { return a + b; }
int multiply(int a, int b) { return a * b; }
int main() {
printf("%d\n", compute(5, 3, add)); // Ausgabe: 8
printf("%d\n", compute(5, 3, multiply)); // Ausgabe: 15
return 0;
}Beachten Sie, wie dieselbe compute Funktion unterschiedliche Ergebnisse liefert, je nachdem, welche Funktion wir übergeben. Dieses Muster ist grundlegend für das Schreiben von flexiblem, wiederverwendbarem Code – Sie schreiben die Struktur einmal, und die Benutzer Ihrer Funktion liefern die spezifische Logik, die sie benötigen.
Aufgabe
EinfachSchreiben Sie eine Funktion apply_twice, die zwei Ganzzahlen und einen Operationscode entgegennimmt, die Operation zweimal hintereinander auf die Zahlen anwendet und das Endergebnis zurückgibt.
Ihre Funktion erhält einen Operationscode, der bestimmt, welche Operation verwendet werden soll. Sie müssen die Operationsfunktionen innerhalb Ihrer Lösung definieren und sie an eine Hilfsfunktion compute übergeben, die einen Funktionszeiger akzeptiert.
Erforderliche Struktur:
- Definieren Sie einen
typedefnamensOperationfür einen Funktionszeiger, der zweiint-Parameter entgegennimmt und einintzurückgibt - Definieren Sie zwei Operationsfunktionen:
add(gibt a + b zurück) undmultiply(gibt a * b zurück) - Definieren Sie eine
compute-Funktion, die zwei Ganzzahlen und einenOperation-Funktionszeiger entgegennimmt und dann das Ergebnis des Aufrufs der Operation zurückgibt - Wählen Sie in
apply_twicedie entsprechende Operation basierend auf dem Code aus und verwenden Siecomputezweimal: zuerst mit den ursprünglichen Zahlen, dann mit dem Ergebnis und der zweiten Zahl erneut
Logik:
- Wählen Sie die Operationsfunktion basierend auf
op_code(1 = add, 2 = multiply) - Rufen Sie
compute(a, b, operation)auf, um ein Zwischenergebnis zu erhalten - Rufen Sie
compute(intermediate, b, operation)auf, um das Endergebnis zu erhalten - Geben Sie das Endergebnis zurück
Parameter:
a(int): Erste Zahlb(int): Zweite Zahlop_code(int): Operationscode (1 für add, 2 für multiply)
Rückgabewert: Das Ergebnis nach der zweimaligen sequenziellen Anwendung der Operation (int)
Beispiel: Mit a = 5, b = 3, op_code = 1 (add):
- Erste Berechnung: 5 + 3 = 8
- Zweite Berechnung: 8 + 3 = 11
- Rückgabe: 11
Mit a = 2, b = 4, op_code = 2 (multiply):
- Erste Berechnung: 2 × 4 = 8
- Zweite Berechnung: 8 × 4 = 32
- Rückgabe: 32
Spickzettel
Funktionszeiger können als Argumente an andere Funktionen übergeben werden, was Callbacks ermöglicht – eine Möglichkeit, benutzerdefiniertes Verhalten einzufügen, ohne den Code der Funktion zu ändern.
Definieren Sie einen Funktionszeigertyp mit typedef:
typedef int (*Operation)(int, int);Erstellen Sie eine Funktion, die einen Funktionszeiger als Parameter akzeptiert:
int compute(int a, int b, Operation op) {
return op(a, b);
}Übergeben Sie verschiedene Funktionen, um unterschiedliche Verhaltensweisen zu erreichen:
int add(int a, int b) { return a + b; }
int multiply(int a, int b) { return a * b; }
int main() {
printf("%d\n", compute(5, 3, add)); // Ausgabe: 8
printf("%d\n", compute(5, 3, multiply)); // Ausgabe: 15
return 0;
}Dieses Muster ermöglicht es Ihnen, flexiblen, wiederverwendbaren Code zu schreiben, bei dem die Struktur einmal definiert wird und Benutzer die spezifische Logik liefern, die sie benötigen.
Probier es selbst
int apply_twice(int a, int b, int op_code) {
// Code hier schreiben
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Object Oriented Programming
1Grundlagen der modularen Programmierung
Header-DateienInclude GuardsQuelldateienStatische FunktionenWiederholung: Modularer Taschenrechner4Kapselung
Konzept der Opaque PointersOpaque Structs definierenGetter und SetterValidierung in SetternRückblick: Die geheime Box7Funktionszeiger
Funktionszeiger deklarierenFunktionszeiger aufrufenTypedef für FunktionszeigerFunktionen als Argumente übergebenZusammenfassung: Calculator Dispatch2Objekte und Methoden
Structs als ObjekteDer 'Self'-PointerConst-CorrectnessPointer vs. WertHilfsmethodenZusammenfassung: Point Manager5Projekt: Einfaches Bankkonto
Projekt-SetupImplementierung des Kontos3Objekt-Lebenszyklus
Konstruktor-MusterDestruktor-MusterStack-InitialisierungTiefe KopieRückblick: String-Wrapper6Vererbung durch Komposition
Struct-EinbettungDie First-Member-RegelZugriff auf Parent-MemberUpcastingRückblick: Formenhierarchie9Projekt: Formen-Zeichner
ProjektübersichtKreis-Implementierung