Fonctions#

Introduction#

Les fonctions sont un élément fondamental de la programmation C++, permettant de regrouper des fragments de code en sections réutilisables et efficaces, conçues pour réaliser une tâche spécifique. Elles peuvent être appelées plusieurs fois au sein d’un programme, ce qui simplifie l’organisation du code et évite les répétitions. Les fonctions facilitent également le débogage.

Cette page aborde les principes de base de l’utilisation des fonctions en C++, notamment :

Structure fonctionnelle et syntaxe#

En C++, les fonctions doivent être déclarées avec leur type de retour, leur nom et leurs paramètres. La syntaxe de base est la suivante :

return_type function_name(parameters) {
  // Code to execute when the function is called
  return result;  // Optional, used to return a value
}

Pièces fonctionnelles

Description

return_type

Le type de données renvoyé par la fonction ; voici quelques options courantes :

  • void — Ne renvoie rien
  • int — Renvoie une valeur entière
  • double — Renvoie un nombre à virgule flottante
  • bool — Renvoie true ou false
  • char — Renvoie un caractère
  • const char* — Renvoie une chaîne de caractères
  • types définis par l’utilisateur — Renvoie un struct ou un objet de classe

function_name

Le nom de la fonction.

parameters

Facultatif. Liste de paramètres typés, séparés par des virgules, sous la forme type name, où type spécifie le type de données du paramètre et name est l’identifiant utilisé pour accéder à cette valeur dans la fonction. Les paramètres reçoivent des valeurs d’entrée lors de l’appel de la fonction.

result

Facultatif. La valeur renvoyée par la fonction. Si le return_type la fonction n’est pas return_typecette valeur doit être fournie et son type doit correspondre exactement au void.

Remarque : Une fonction doit toujours être déclarée avant d’être appelée, ou vous devez fournir un prototype de fonction.

Prototypes fonctionnels#

En C++, le code est lu de haut en bas. Cela signifie qu’une fonction doit être connue du compilateur avant de pouvoir être appelée.

Un prototype de fonction permet d’utiliser une fonction avant d’écrire son code complet. Cela permet de conserver main() en haut du programme, tout en plaçant les définitions de fonctions plus tard, où elles sont plus faciles à organiser et à lire.

Sans prototype, vous devriez définir chaque fonction au-dessus de main(), ce qui peut rendre les projets plus difficiles à suivre à mesure qu’ils se développent.

Définir le prototype de la fonction (en dehors de int main())

// The function's prototype
void greeting();

Appelez la fonction à l’intérieur de int main()

int main() {
  /* vexcodeInit() is only required when using VEXcode.
  Remove vexcodeInit() if compiling in VS Code. */
  vexcodeInit();

  greeting();
}

Écrivez le corps de la fonction après

void greeting() {
  Brain.Screen.print("Hello!");
}

Définition et appel de fonctions#

Functions with No Parameters#

Si une fonction ne requiert pas d’entrée, vous pouvez la définir sans paramètres. Utilisez void comme type de retour si la fonction ne renvoie aucune valeur.

Définissez la fonction (en dehors de int main())

// Define a function to display a message
void greeting() {
    Brain.Screen.print("Hello!");
}

Appelez la fonction à l’intérieur de int main()

int main() {
  /* vexcodeInit() is only required when using VEXcode.
  Remove vexcodeInit() if compiling in VS Code. */
  vexcodeInit();

  // Call the function to display the message
  greeting();
}

Functions with Parameters#

Vous pouvez également ajouter des paramètres aux fonctions, ce qui vous permet de leur transmettre des informations à utiliser.

Remarque : Le texte peut être transmis à l’aide de chaînes de caractères de style C (const char*) ou de chaînes de caractères C++ (std::string).

Définissez la fonction (en dehors de int main())

// Define a function with a parameter
void namedGreeting(const char* name) {
    Brain.Screen.print("Hello, %s!", name);
}

Appelez la fonction avec un paramètre à l’intérieur de int main()

int main() {
  /* vexcodeInit() is only required when using VEXcode.
  Remove vexcodeInit() if compiling in VS Code. */
  vexcodeInit();

  // Call the function to display the message
  namedGreeting("Stranger");
}

Valeurs de retour#

Les fonctions peuvent renvoyer des données à l’appelant grâce au mot-clé return . Cela vous permet de récupérer et d’utiliser la sortie dans votre projet.

Définissez la fonction (en dehors de int main())

// Define a function that multiplies numbers by 2
int timesTwo(int number) {
    return number * 2;
}

Appelez la fonction avec un paramètre à l’intérieur de int main()

int main() {
  /* vexcodeInit() is only required when using VEXcode.
  Remove vexcodeInit() if compiling in VS Code. */
  vexcodeInit();

  // Display the return value
  Brain.Screen.print("%d", timesTwo(2));
}

Passage par référence#

By default, C++ passes function parameters by value, meaning the function receives a copy of the original variable. Changes made inside the function do not affect the original value.

Définissez la fonction (en dehors de int main())

// Add 1 to the number
void addOne(int number) {
  number++;
}

Appelez la fonction avec un paramètre à l’intérieur de int main()

int main() {
  /* vexcodeInit() is only required when using VEXcode.
  Remove vexcodeInit() if compiling in VS Code. */
  vexcodeInit();

  int value = 5;
  addOne(value);
  // "value" will still be 5
}

Pour permettre à une fonction de modifier la variable d’origine, les paramètres peuvent être passés par référence en utilisant le symbole &.

Définissez la fonction (en dehors de int main())

// Add 1 to the number
void addOne(int& number) {
  number++;
}

Appelez la fonction avec un paramètre à l’intérieur de int main()

int main() {
  /* vexcodeInit() is only required when using VEXcode.
  Remove vexcodeInit() if compiling in VS Code. */
  vexcodeInit();

  int value = 5;
  addOne(value);
  // "value" will now be 6
}

Le passage par référence permet aux fonctions de mettre à jour les variables définies en dehors de la fonction sans renvoyer de valeur.

Fonctions de rappel#

Une fonction de rappel est une fonction qui est passée en paramètre à une autre fonction et appelée automatiquement lorsqu’un événement spécifique se produit.

Les fonctions de rappel sont couramment utilisées pour des événements tels que les appuis sur un bouton ou les mises à jour de capteurs.

Au lieu d’appeler vous-même la fonction, le projet l’appelle pour vous lorsque l’événement se produit.

Définissez la fonction de rappel (en dehors de int main())

// Create a callback function
void onPressed() {
  Brain.Screen.print("Screen pressed!");
}

Enregistrez le rappel à l’intérieur de int main()

int main() {
  /* vexcodeInit() is only required when using VEXcode.
  Remove vexcodeInit() if compiling in VS Code. */
  vexcodeInit();

  // Call onPressed whenever the screen is pressed
  Brain.Screen.pressed(onPressed);
}

Callback Signatures#

Chaque fonction de rappel doit respecter une signature spécifique, qui définit :

  • Le type de retour

  • Le nombre de paramètres

  • Les types de paramètres

La signature requise est déterminée par l’API. La fonction de rappel doit correspondre exactement à cette signature.

// This callback function cannot include any parameters
void callback(void);

// This callback function includes four parameters
void callback(axisType axis, double x, double y, double z);

Les noms des paramètres sont descriptifs et peuvent varier, mais le type de retour, l’ordre des paramètres et les types des paramètres doivent correspondre exactement.

Fonctions avec arguments par défaut#

Les fonctions peuvent définir des valeurs par défaut pour un ou plusieurs paramètres. Un argument par défaut est utilisé lorsqu’aucune valeur n’est fournie pour ce paramètre lors de l’appel de la fonction.

Règles relatives aux arguments par défaut :

  • Les arguments par défaut doivent être les derniers paramètres de la définition de la fonction.

  • Dès lors qu’un paramètre possède une valeur par défaut, tous les paramètres suivants doivent également avoir une valeur par défaut.

  • Si une fonction spécifie des arguments par défaut dans son prototype, ces valeurs par défaut ne doivent pas être spécifiées à nouveau dans la définition de la fonction.

Définissez la fonction (en dehors de int main())

// Required parameter first, default parameter last
void greeting(const char* name, int repeatCount = 1) {

    for (int i = 0; i < repeatCount; i++) {
        Brain.Screen.print("Hello, %s!", name);
        Brain.Screen.newLine();
    }
}

Appelez la fonction à l’intérieur de int main()

int main() {
  /* vexcodeInit() is only required when using VEXcode.
  Remove vexcodeInit() if compiling in VS Code. */
  vexcodeInit();

  // Say what name to greet (EXP) and
  // use default value for repeatCount (1)
  greeting("EXP");

  Brain.Screen.newLine();

  // Overrides the default value to 3
  greeting("EXP", 3);
}

// Required parameter first, default parameter last
void greeting(const char* name, int repeatCount = 1) {

    for (int i = 0; i < repeatCount; i++) {
        Brain.Screen.print("Hello, %s!", name);
        Brain.Screen.newLine();
    }
}

int main() {
    vexcodeInit();

    // Say what name to greet (EXP) and
    // use default value for repeatCount (1)
    greeting("EXP");

    Brain.Screen.newLine();

    // Overrides the default value to 3
    greeting("EXP", 3);
}