Implémentation de fonctions de rappel en C

CCBeginner
Pratiquer maintenant

💡 Ce tutoriel est traduit par l'IA à partir de la version anglaise. Pour voir la version originale, vous pouvez cliquer ici

Introduction

Dans ce projet, vous allez apprendre à implémenter une fonction de rappel en langage C. Les fonctions de rappel sont une technique puissante en programmation C, en particulier dans le contexte du développement de systèmes Linux, où elles sont couramment utilisées.

👀 Aperçu

$ gcc test_callback.c callback.c -o test_callback
$./test_callback
Alarm1:0
Alarm2:1
Alarm3:2

🎯 Tâches

Dans ce projet, vous allez apprendre :

  • Comment définir et utiliser des fonctions de rappel en C
  • Comment enregistrer et déclencher des alarmes à l'aide d'une fonction de rappel
  • Comment gérer les cas limites et les erreurs dans l'implémentation de la fonction de rappel

🏆 Réalisations

Après avoir terminé ce projet, vous serez capable de :

  • Comprendre le concept de fonctions de rappel et leur utilisation en programmation C
  • Implémenter un système d'alarme basé sur des rappels, y compris l'enregistrement et le déclenchement d'alarmes
  • Écrire un code robuste et défensif pour gérer les problèmes potentiels dans la fonction de rappel
  • Appliquer vos connaissances sur les fonctions de rappel à d'autres domaines de la programmation C, tels que les systèmes événementiels ou les opérations asynchrones

Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL c(("C")) -.-> c/PointersandMemoryGroup(["Pointers and Memory"]) c(("C")) -.-> c/FunctionsGroup(["Functions"]) c(("C")) -.-> c/UserInteractionGroup(["User Interaction"]) c(("C")) -.-> c/CompoundTypesGroup(["Compound Types"]) c/CompoundTypesGroup -.-> c/arrays("Arrays") c/PointersandMemoryGroup -.-> c/pointers("Pointers") c/FunctionsGroup -.-> c/function_declaration("Function Declaration") c/FunctionsGroup -.-> c/function_parameters("Function Parameters") c/UserInteractionGroup -.-> c/output("Output") subgraph Lab Skills c/arrays -.-> lab-301493{{"Implémentation de fonctions de rappel en C"}} c/pointers -.-> lab-301493{{"Implémentation de fonctions de rappel en C"}} c/function_declaration -.-> lab-301493{{"Implémentation de fonctions de rappel en C"}} c/function_parameters -.-> lab-301493{{"Implémentation de fonctions de rappel en C"}} c/output -.-> lab-301493{{"Implémentation de fonctions de rappel en C"}} end

Comprendre la fonction de rappel

Dans cette étape, vous allez apprendre le concept des fonctions de rappel en langage C et la manière dont elles sont utilisées dans le développement de programmes C pour Linux.

Les fonctions de rappel sont un moyen de passer une fonction en tant qu'argument à une autre fonction, qui peut ensuite appeler la fonction passée plus tard. Il s'agit d'une technique puissante qui permet d'avoir un code plus flexible et modulaire.

Dans le code fourni dans le fichier callback.c, la fonction de rappel est utilisée pour implémenter un système d'alarme. La structure alarm représente une alarme, et la fonction register_alarm est utilisée pour enregistrer une alarme. La fonction hit_alarm est ensuite utilisée pour déclencher les alarmes enregistrées.

Identifier et corriger les défauts

Maintenant, regardons le code fourni dans le fichier callback.c et corrigons les défauts.

  1. Segmentation Fault : Il est probable que alarm_list ne soit pas correctement rempli ou consulté, ce qui peut entraîner un accès mémoire illégal.
  2. Gestion incorrecte de l'index dans register_alarm : La variable index est locale à register_alarm et est réinitialisée à 0 chaque fois que la fonction est appelée. Cela fait en sorte que toutes les alarmes soient enregistrées à l'index 1, en écrasant les autres.

Mettez à jour le fichier callback.c comme suit :

#include "callback.h"

alarm alarm_list[MAX_ALARMS];
int current_index = 0; // Global index tracker

void register_alarm(alarm a) {
    if (current_index < MAX_ALARMS) {
        alarm_list[current_index] = a;
        current_index++;
    }
    // If the number of registered alarms exceeds MAX_ALARMS, do nothing (don't report an error)
}

int hit_alarm(int index) {
    if (index < 0 || index >= MAX_ALARMS ||!alarm_list[index])
        return 1;
    (*alarm_list[index])(index);
    return 0;
}

Les principales modifications sont les suivantes :

  1. Ajout d'une variable globale current_index pour suivre l'index actuel pour enregistrer les alarmes.
  2. Dans register_alarm, nous vérifions si current_index est inférieur à MAX_ALARMS avant d'enregistrer l'alarme. Si le nombre d'alarmes enregistrées dépasse MAX_ALARMS, nous ne signalons pas d'erreur et continuons simplement.
  3. Dans hit_alarm, nous avons ajouté des vérifications supplémentaires pour vous assurer que l'index est dans la plage valide et qu'une alarme est effectivement enregistrée à cet index. Sinon, nous retournons 1 pour indiquer qu'aucune alarme n'a été déclenchée.

Tester la fonction de rappel

Maintenant que nous avons corrigé les défauts dans le fichier callback.c, testons la fonction de rappel en exécutant le programme test_callback.c fourni.

Compilez le programme :

gcc test_callback.c callback.c -o test_callback

Exécutez le programme :

./test_callback

Sortie :

Alarm1:0
Alarm2:1
Alarm3:2

La sortie devrait maintenant correspondre à la sortie attendue, et le programme devrait s'exécuter sans aucun défaut de segmentation ou d'autres erreurs.

Félicitations ! Vous avez réussi à déboguer et corriger l'implémentation de la fonction de rappel.

✨ Vérifier la solution et pratiquer

Sommaire

Félicitations ! Vous avez terminé ce projet. Vous pouvez pratiquer plus de laboratoires sur LabEx pour améliorer vos compétences.