Fonction de rappel en C

Bonjour, futurs programmeurs ! Aujourd'hui, nous plongeons dans le monde fascinant des fonctions de rappel en C. En tant que votre enseignant de science informatique bienveillant, je suis excité de vous guider à travers ce concept. Faites-moi confiance, une fois que vous aurez compris les rappels, vous vous sentirez comme si vous aviez déverrouillé une nouvelle superpuissance dans la programmation !

C - Callback Function

Qu'est-ce qu'une fonction de rappel ?

Commençons par les bases. Imaginez que vous êtes à une fête de pizza (qui n'aime pas la pizza ?) et que vous demandez à votre ami de vous appeler lorsque la pizza arrive. Votre ami effectue essentiellement un rappel - il vous appelle lorsque se produit un événement spécifique.

En programmation C, une fonction de rappel fonctionne de manière similaire. C'est une fonction que nous passons comme argument à une autre fonction. Cette autre fonction "appelle en retour" (exécute) la fonction transmise lorsque se produit un certain événement ou qu'une tâche est terminée.

Voici une structure simple d'une fonction de rappel :

void fonction_rappel() {
// Corps de la fonction
}

void fonction_principale(void (*rappel)()) {
// Un peu de code
rappel();  // Appel de la fonction de rappel
// Plus de code
}

int main() {
fonction_principale(fonction_rappel);
return 0;
}

Dans cet exemple, fonction_rappel est notre rappel. Nous le passons à fonction_principale, qui l'appelle à un moment donné pendant son exécution.

Exemple de fonction de rappel en C

Voyons un exemple plus concret. Nous allons créer un programme simple qui utilise un rappel pour imprimer un message après une calcul.

#include <stdio.h>

// Notre fonction de rappel
void imprimer_resultat(int resultat) {
printf("Le résultat est : %d\n", resultat);
}

// Fonction qui effectue un calcul et appelle le rappel
void effectuer_operation(int a, int b, void (*rappel)(int)) {
int somme = a + b;
rappel(somme);  // Appel de la fonction de rappel avec le résultat
}

int main() {
effectuer_operation(5, 3, imprimer_resultat);
return 0;
}

Dans cet exemple :

  1. Nous définissons une fonction de rappel imprimer_resultat qui prend un entier et l'imprime.
  2. Notre fonction effectuer_operation prend deux entiers et un pointeur de fonction comme arguments.
  3. À l'intérieur de effectuer_operation, nous calculons la somme et appelons la fonction de rappel avec cette somme.
  4. Dans main, nous appelons effectuer_operation avec nos nombres et le rappel imprimer_resultat.

Lorsque vous exécutez ce programme, il affichera : "Le résultat est : 8"

Fonction de rappel avec des arguments

Les rappels peuvent également prendre plusieurs arguments. Élargissons notre exemple précédent pour inclure plus d'opérations :

#include <stdio.h>

// Fonction de rappel avec plusieurs arguments
void imprimer_operation(char operation, int a, int b, int resultat) {
printf("%d %c %d = %d\n", a, operation, b, resultat);
}

// Fonction qui effectue un calcul et appelle le rappel
void effectuer_operation(int a, int b, char op, void (*rappel)(char, int, int, int)) {
int resultat;
switch(op) {
case '+': resultat = a + b; break;
case '-': resultat = a - b; break;
case '*': resultat = a * b; break;
case '/': resultat = a / b; break;
default: printf("Opération invalide\n"); return;
}
rappel(op, a, b, resultat);
}

int main() {
effectuer_operation(5, 3, '+', imprimer_operation);
effectuer_operation(10, 4, '-', imprimer_operation);
effectuer_operation(7, 2, '*', imprimer_operation);
effectuer_operation(20, 5, '/', imprimer_operation);
return 0;
}

Ce programme affichera :

5 + 3 = 8
10 - 4 = 6
7 * 2 = 14
20 / 5 = 4

Ici, notre fonction de rappel imprimer_operation prend quatre arguments : l'opération, deux opérandes, et le résultat. Cela nous permet de créer une sortie plus flexible et informative.

Types de rappels en C

En C, nous pouvons classifier les rappels en deux types principaux :

  1. Rappels synchrones : Ceux-ci sont exécutés immédiatement par la fonction à laquelle ils sont passés. Nos exemples ci-dessus sont des rappels synchrones.

  2. Rappels asynchrones : Ceux-ci sont planifiés pour être exécutés plus tard, souvent utilisés dans la programmation événementielle ou lors de la manipulation des opérations E/S.

Voyons un tableau récapitulatif de ces types :

Type Description Cas d'utilisation Exemple
Synchrones Exécutés immédiatement Opérations simples, calculs Notre exemple d'opérations arithmétiques
Asynchrones Exécutés plus tard Gestion des événements, opérations E/S Callbacks de lecture/écriture de fichiers, gestionnaires d'événements GUI

Voici un exemple simple d'un rappel asynchrone en utilisant les signaux en C :

#include <stdio.h>
#include <signal.h>
#include <unistd.h>

void fonction_rappel(int signum) {
printf("Signal reçu %d\n", signum);
}

int main() {
signal(SIGALRM, fonction_rappel);
alarm(5);  // Définir une alarme pour 5 secondes

printf("En attente de l'alarme...\n");
pause();  // Attente d'un signal

return 0;
}

Dans cet exemple, fonction_rappel est configuré comme un rappel asynchrone qui sera appelé lorsque le signal SIGALRM est reçu. La fonction alarm(5) définit un minuteur de 5 secondes, après quoi le signal SIGALRM est envoyé, déclenchant notre fonction de rappel.

Et voilà, amis ! Nous avons traversé le pays des fonctions de rappel en C. Souvenez-vous, les rappels sont comme des sidekicks fidèles dans vos aventures de programmation - ils sont toujours là lorsque vous en avez besoin, prêts à entrer en action. Continuez à vous entraîner, et bientôt vous maîtriserez les rappels comme un pro !

Credits: Image by storyset