Déclaration de pointeurs sur fonctions
Fait partie de la section Object Oriented Programming du Journey C de Coddy — leçon 33 sur 61.
Jusqu'à présent, nous avons appris à simuler l'héritage en utilisant l'imbrication de structures (struct embedding). Mais le véritable polymorphisme — où différents objets répondent différemment au même appel — nécessite quelque chose de plus : les pointeurs de fonction (function pointers).
Un pointeur de fonction est une variable qui stocke l'adresse d'une fonction. Tout comme un pointeur classique contient l'adresse de données, un pointeur de fonction contient l'adresse de code exécutable.
La syntaxe peut sembler intimidante au premier abord. Pour déclarer un pointeur de fonction, vous spécifiez le type de retour, puis le nom du pointeur entre parenthèses avec un astérisque, suivi des types de paramètres :
int (*operation)(int, int);Ceci déclare une variable appelée operation qui peut pointer vers n'importe quelle fonction prenant deux paramètres int et retournant un int. Les parenthèses autour de *operation sont cruciales — sans elles, vous déclareriez une fonction qui retourne un pointeur.
Pour assigner une fonction à ce pointeur, utilisez simplement le nom de la fonction (sans parenthèses) :
int add(int a, int b) {
return a + b;
}
int (*operation)(int, int);
operation = add; // Maintenant operation pointe vers addLe nom de la fonction fait office d'adresse. Vous pouvez également utiliser &add explicitement, mais c'est facultatif — les deux formes sont équivalentes en C.
Défi
FacilePratiquons la déclaration de pointeurs de fonction et l'assignation de fonctions à ceux-ci. Vous allez créer un système d'opération mathématique simple où un pointeur de fonction peut contenir différentes fonctions arithmétiques.
Écrivez un programme qui :
- Définit deux fonctions :
multiply— prend deux paramètresintet retourne leur produitsubtract— prend deux paramètresintet retourne le premier moins le second
- Dans
main, déclare une variable de pointeur de fonction appeléeoperationqui peut pointer vers des fonctions prenant deux paramètresintet retournant unint - Lit trois entrées : deux entiers et un code d'opération (1 pour multiply, 2 pour subtract)
- Selon le code d'opération, assigne la fonction appropriée à votre pointeur
operation - Affiche le nom de l'opération assignée, puis affiche le résultat de l'appel de la fonction via le pointeur
Vous recevrez trois entrées : le premier nombre, le second nombre, et le code d'opération (1 ou 2).
Votre sortie devrait ressembler à ceci :
Operation: multiply
Result: 35Où multiply est le nom de l'opération (ou subtract si le code est 2), et 35 est le résultat de l'appel de la fonction via votre pointeur (dans ce cas, 5 × 7).
Rappel : pour déclarer le pointeur de fonction, vous avez besoin du type de retour, du nom du pointeur entre parenthèses avec un astérisque, et des types de paramètres. Pour assigner une fonction, utilisez simplement le nom de la fonction sans parenthèses.
Aide-mémoire
Un pointeur de fonction est une variable qui stocke l'adresse d'une fonction, permettant le polymorphisme en autorisant l'appel de différentes fonctions via le même pointeur.
Déclarer un pointeur de fonction
La syntaxe spécifie le type de retour, le nom du pointeur avec une astérisque entre parenthèses, et les types de paramètres :
int (*operation)(int, int);Ceci déclare operation comme un pointeur vers n'importe quelle fonction qui prend deux paramètres int et retourne un int. Les parenthèses autour de *operation sont essentielles.
Assigner une fonction à un pointeur
Utilisez le nom de la fonction sans parenthèses :
int add(int a, int b) {
return a + b;
}
int (*operation)(int, int);
operation = add; // operation points now to addLe nom de la fonction fait office d'adresse. Vous pouvez également utiliser &add explicitement, mais c'est facultatif.
Essayez vous-même
#include <stdio.h>
// TODO: Définir la fonction de multiplication ici
// TODO: Définir la fonction de soustraction ici
int main() {
int num1, num2, code;
// Lire l'entrée
scanf("%d", &num1);
scanf("%d", &num2);
scanf("%d", &code);
// TODO: Déclarer un pointeur de fonction nommé 'operation' qui peut pointer vers
// des fonctions prenant deux paramètres int et retournant un int
// TODO: En fonction du code d'opération (1 pour multiplier, 2 pour soustraire),
// assigner la fonction appropriée à votre pointeur d'opération
// TODO: Afficher le nom de l'opération et le résultat
// Format:
// Operation: <name>
// Result: <result>
return 0;
}Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Object Oriented Programming
1Bases de la programmation modulaire
Fichiers d'en-têteGardes d'inclusionFichiers sourcesFonctions statiquesRécapitulatif : Calculatrice modulaire4Encapsulation
Concept des pointeurs opaquesDéfinir des structures opaquesGetters et settersValidation dans les settersRécapitulatif : La boîte secrète7Pointeurs sur fonctions
Déclaration de pointeurs sur fonctionsAppel de pointeurs sur fonctionsTypedef pour les pointeurs sur fonctionsPassage de fonctions en argumentsRécapitulatif : Dispatcher de calculatrice2Objets et méthodes
Structs comme objetsLe pointeur 'Self'Rigueur du mot-clé constPointeur vs ValeurMéthodes utilitairesRécapitulatif : Point Manager5Projet : Compte bancaire simple
Configuration du projetImplémentation du compte8Polymorphisme
Pointeurs de fonctions dans les structuresSimulation de méthodesLe concept d'interfaceImplémentation d'interfacesItération polymorphiqueRécapitulatif : Greeter11Patrons de conception en C
Patron SingletonPatron FabriquePatron ItérateurRécapitulatif : Logger Factory3Cycle de vie des objets
Pattern de constructeurPattern de destructeurInitialisation sur la pileCopie profondeRécapitulatif : String Wrapper6Héritage par composition
Imbrication de structLa règle du premier membreAccès aux membres parentsUpcastingRécapitulatif : Hiérarchie des formes9Projet : Dessinateur de formes
Aperçu du projetImplémentation du cercle