# Routine (informatique)

En informatique, une routine est une entité informatique qui encapsule une portion de code (une séquence d'instructions) effectuant un traitement spécifique bien identifié (asservissement, tâche, calcul, etc.) relativement indépendant du reste du programme.
Elle peut également être réutilisée dans le même programme, ou dans un autre. Dans ce cas, on range souvent la routine dans une bibliothèque pour la rendre disponible à d'autres projets de programmation, tout en préservant l'intégrité de son implémentation.
Les routines permettent de structurer la programmation d'un problème en décomposant le programme à réaliser en portions de code plus faciles à produire, à utiliser, à gérer et à entretenir. Les instructions réalisant la routine sont encapsulées à l'intérieur de celle-ci et le programmeur peut faire appel à la routine sans se préoccuper des détails internes à celle-ci ; la routine joue le rôle d'une boite noire dans les routines qui l'emploient.

## Sortes de routines

En programmation informatique, on retrouve les routines sous deux formes principales :
| la procédure | Une routine qui ne renvoie aucune valeur, réalise une opération (tâche) bien déterminée et dont l'emploi joue le rôle d'une instruction ad-hoc. |
| la fonction | Une routine qui renvoie une et une seule valeur, conformément à la définition mathématique de fonction. |
Une routine est effective seulement si elle renvoie au moins une valeur à la routine appelante ou (inclusif) si elle a un effet sur son environnement : lecture d'un capteur, écriture sur un actionneur, altération d'une variable globale, etc.

### Cas particuliers

| routine prédéfinie | Une routine fournie, le plus souvent dans une bibliothèque, qui peut être utilisée sans avoir à la définir, si on connait sa déclaration et son rôle. |
| routine factice | Une routine qui, à titre provisoire au cours du développement du programme, ne fait rien (le corps de la routine est vide). |
| méthode | Une routine qui est membre d'une classe (en programmation orientée objet) |

## Déclaration

Dans la plupart des langages de programmation, la déclaration (et par conséquent la définition) d'une routine comporte en général :
* un mot-clé (procedure, function, action, etc.) dans le cas d'une routine dans un langage distinguant clairement les diverses formes de routine ;
* l'identifiant de la routine (nom donné par le programmeur à la routine) ;
* la description des paramètres indiquant pour chacun (s'il y a des paramètres) :
** l'identifiant (nom) du paramètre,
** le type (explicite ou implicite) du paramètre (dans le cas d'une routine dans un langage typé).
Dans le cas d'une fonction, la déclaration de la routine comporte aussi :
* le type de la routine (dans le cas d'une fonction d'un langage typé), c'est-à-dire le type de sa valeur de retour.
Exemple de déclaration très simple en langage C :
| | Mot-clef | Type | Identifiant | Paramètres | Paramètres | Paramètres | Paramètres | Paramètres | Paramètres | Paramètres |
| | (aucun) | (de la valeur renvoyée) | (de la routine) | | Type | Identifiant | | Type | Identifiant | |
| Déclaration | | int | Somme | ( | int | Parm1 | , | int | Parm2 | ); |
Dans le cas d'une fonction, la définition de la routine comporte aussi :
* un corps contenant le code réalisant l'opération dévolue à cette routine ;
* l'affectation, dans le corps de la routine, d'un résultat à la valeur de retour de la fonction.
Exemple de définition très simple en langage C :
| | Mot-clef | Type | Identifiant | Paramètres | Paramètres | Paramètres | Paramètres | Paramètres | Paramètres | Paramètres |
| | (aucun) | (de la valeur renvoyée) | (de la routine) | | Type | Identifiant | | Type | Identifiant | |
| Déclaration | | int | Somme | ( | int | Parm1 | , | int | Parm2 | ) |
| Corps | | { return Var1 + Var2; // Affectation d'un résultat à la valeur de retour de la fonction. } | { return Var1 + Var2; // Affectation d'un résultat à la valeur de retour de la fonction. } | { return Var1 + Var2; // Affectation d'un résultat à la valeur de retour de la fonction. } | { return Var1 + Var2; // Affectation d'un résultat à la valeur de retour de la fonction. } | { return Var1 + Var2; // Affectation d'un résultat à la valeur de retour de la fonction. } | { return Var1 + Var2; // Affectation d'un résultat à la valeur de retour de la fonction. } | { return Var1 + Var2; // Affectation d'un résultat à la valeur de retour de la fonction. } | { return Var1 + Var2; // Affectation d'un résultat à la valeur de retour de la fonction. } | { return Var1 + Var2; // Affectation d'un résultat à la valeur de retour de la fonction. } |
Dans certains langages de programmation qui le permettent, ce qui est rare aujourd'hui (2016), on précise le mode d'échange associé à chaque paramètre :
* un paramètre en entrée permet à la routine de recevoir un argument, mais pas d'y écrire ;
* un paramètre en sortie permet à la routine d'écrire dans l'argument ;
* un paramètre à modifier permet à la routine de recevoir un argument et d'y écrire.
Tous ces éléments n'apparaissent pas forcément dans tous les langages de programmation.

### Signature d'une routine (décoration de nom)

La signature (profil) d'une routine, ou décoration de nom, permet au traducteur (compilateur, interpréteur, etc.) de vérifier que la routine est employée de façon cohérente avec sa déclaration. Elle permet aussi au lieur (éditeur de liens) d'établir le lien avec la routine correspondante.
La signature utilise habituellement :
* le type de la routine ;
* l'identifiant de la routine ;
* la liste des spécifications des paramètres.

### Paramètres

Dans les langages de programmation d'autrefois (par exemple, en FORTRAN IV), la routine appelée travaillait directement sur les variables de la routine appelante. À l'inverse, dans la plupart des langages de programmation modernes, la routine appelante fait une copie des arguments et transmet uniquement cette valeur copiée à la routine appelée. On parle ainsi de passage de paramètres par valeur. Il est toujours possible de travailler sur des variables sans copie, si celles ci ont été déclarées « globales ». On parle alors de programmation par effet de bord.
Cependant, les routines demandent souvent l'adresse mémoire des variables de la routine appelante (arguments) plutôt que leurs valeurs. Ce mécanisme utilise un pointeur (ou une référence, en C++, Perl ou PHP). Normalement, par souci de modularité, une routine ne renvoie pas de valeur par modification des variables de la routine appelante (arguments). Par exemple, en Fortran, cela est formellement interdit par les spécifications du langage et détecté par les compilateurs. Une fonction peut renvoyer un seul résultat par sa valeur de retour. Ce résultat peut, entre autres, être :
* de grande taille, comme une chaîne de caractères en PL/I ou une structure en C ;
* une adresse en mémoire ;
* un simple code d'erreur (en) (par exemple 0 si l'opération s'est bien terminée).

### Corps de la routine

Le corps de la routine comprend :
* la définition des variables locales à la routine, certaines de ces variables n'existant que le temps de son exécution ;
* la séquence des instructions à exécuter.

### Exemple générique

Soit à écrire trois nombres par ordre croissant, on aura par exemple :
| Code | Explication |
| programme p1; | |
| // Variables globales au programme. réel r1, r2, r3 ; | |
| //******************************************** fonction min(réel a, b) : réel; début // Déterminer la valeur minimale. si a < b alors min := a ; sinon min := b ; fin min; //******************************************** fonction max(réel a, b) : réel; début // Déterminer la valeur maximale en utilisant la fonction min. max := ( a+b - min(a,b) ) fin max; | S'utilisant comme en mathématiques, les fonctions min et max définies ici : ont un profil du style (réel, réel)→réel : avec 2 réels, elles en produisent un troisième, distinct ou non ; ont les paramètres a et b (noms internes aux routines des valeurs fournies) ; renvoient leur valeur par l'affectation à min (ou max, selon le nom de la routine). La routine max : exploite la routine min par la relation a+b = min(a,b)+max(a,b). |
| //******************************************** action classeETsort(réel a, b, c) // Variables locales à la procédure. réel inf, sup ; début // inf reçoit la plus petite valeur. inf:= min(a, min(b, c)); // sup reçoit la plus grande valeur. sup:= max(a, max(b, c)); // Afficher le triplet ordonné. écrire (inf, a+b+c-inf-sup, sup) ; fin classeETsort; | La procédure (ou l'action) classeETsort : a pour profil (réel, réel, réel), et a, b, c désignent les paramètres (noms internes des valeurs à traiter) ; reçoit, lors de son appel par la routine principale, une copie des arguments (ou valeurs externes) r1, r2 et r3 dans ses aux paramètres a, b, c ; passe directement les résultats à l'extérieur ; comporte les variables locales inf et sup (pour la mémorisation de valeurs intermédiaires). |
| //******************************************** début // Lire les 3 valeurs à trier. lire(r1); lire(r2); lire(r3 ); // Trier les 3 valeurs et les afficher // en utilisant la procédure classeETsort. classeETsort(r1, r2, r3); fin p1. | La routine principale du programme : utilise la routine lire, qui est un exemple d'action initialisant la variable indiquée, pour lire auprès de l'utilisateur du programme, les valeurs à trier utilise la procédure classeETsort pour afficher les valeurs triées. Les routines lire (dans la routine principale) et écrire (dans la routine classeETsort) sont supposées prédéfinies ; |

### Exemple de fonction en C

| int max ( int a, int b ) { return a > b ? a : b; } | La fonction max a pour paramètres a et b de type entier (int) et renvoie une valeur de type entier (int). Les accolades { et } délimitent le corps de la fonction. Le nom de la fonction (max) décrit bien l'opération qu'elle effectue; elle renvoie la valeur maximale entre a et b. Ce n'est pas une obligation du langage, mais constitue une bonne pratique de programmation : le nom de la fonction n'a d'importance que mnémotechnique, son comportement ne dépendant que des instructions dans son corps. Dans certains langages, le nom de la fonction a une importance particulière. Par exemple, en C++, les constructeurs et destructeurs doivent porter le nom de la classe correspondante. |
| int main ( int argc, char *argv ) { //... printf ( "La valeur maximum est %i.\n", max(123,456) ); //... return 0; } | La fonction principale (main) utilise la fonction max (on parle « d'appel de fonction ») en argument de la fonction printf : max(123, 456). |

### Implémentation

Tous les langages de programmation n'implémentent pas les deux formes de routines. Les langages qui implémentent les deux formes de routines réservent un mot-clef pour les distinguer lors de leur déclaration.
Exemples de mots clefs utilisés :
| Langage | Procédure | Fonction |
| Lisp | Cas particulier de fonction | defun |
| C, C++ | Cas particulier de fonction : type spécial de retour void | Aucun mot clef |
| Pascal | PROCEDURE | FUNCTION |
| Fortran | subroutine | function |
| Algol | procedure | Cas particulier de procédure |
Avec certains langages de programmation, les deux concepts sont proches, la distinction ne se faisant que dans le fait de renvoyer ou non une valeur ou lorsqu'une procédure tient lieu de fonction avec des résultats multiples ou si une fonction réalise des opérations d'entrée/sortie.
Par contre, dans le cas de langages n'admettant, au côté des procédures, que des fonctions pures, les deux concepts sont très distinct.
Par exemple, en langage C/C++ ou en Lisp toutes les routines sont des fonctions ; c'est pourquoi la documentation du langage ne parle que de fonction. Par contre, afin d'avoir l'équivalent de la procédure et pour convertir facilement des programmes écrits dans des langages ayant des procédures, le langage C/C++ fournit le type void qui permet de déclarer une fonction qui ne renvoie rien, ce qui en fait une procédure.
En langage C/C++, la valeur de retour de certaines fonctions, telles que printf (écriture sur le flux de sortie stdout) ou scanf (lecture sur le flux d'entrée stdin), qui rend compte de leur exécution, est plus souvent négligée par la routine qui les utilise ; ces fonctions jouent alors essentiellement un rôle d'instruction, comme une procédure.
En Algol W, toute routine renvoie une valeur, qu'on peut utiliser ou non, ce qui ressemble à l'approche du langage C.
PL/I ne considère une procédure que comme une fonction dont le résultat n'est pas mémorisé, ce qui ressemble aussi à l'approche du langage C. Par contre, les langages comme Fortran, Algol 60, BASIC, Pascal, Modula 2 distinguent clairement les deux concepts en utilisant des mots-clefs.
Exemples très simples en langage C :
| | Déclaration | Définition |
| Fonction | int somme(int var1, int var2); | int somme(int var1, int var2) { return var1 + var2; } |
| Procédure | void afficher(int var); | void afficher (int var) { printf ("Valeur = %i\n", var) ; return; } |