(C++) Sous-routines : procédures et fonctions - 1


Sous-programmes
Une sous-routine est une partie distincte du programme qui a un nom et résout sa propre tâche distincte. Le sous-programme est situé au début du programme principal et peut être lancé (appelé) à partir du programme principal en spécifiant le nom.

L'utilisation de sous-programmes vous permet d'éviter la duplication de code, si vous devez écrire le même code à différents endroits du programme. 
Les bibliothèques importées dans le programme (par exemple, la bibliothèque mathématique сmath.h) sont constituées de sous-programmes qui ont déjà été compilés par quelqu'un. Les programmeurs n'ont pas besoin de réfléchir aux algorithmes qu'ils implémentent, mais simplement de les appliquer, en pensant uniquement à ce qu'ils font exactement. C'est un gain de temps considérable. Il n'est pas nécessaire d'écrire un algorithme qui a déjà été écrit par quelqu'un d'autre.

Chaque routine ne doit effectuer qu'une seule tâche,  soit simplement calculer quelque chose, soit générer des données, soit faire autre chose. 

Les sous-programmes sont de deux types - procédures et fonctions.

Les sous-programmes effectuent certaines actions, par exemple, affichent le résultat à l'écran sous une certaine forme (un exemple simple, l'opérateur printf()  ; est un sous-programme standard qui imprime des informations à l'écran)

Les sous-routines de fonctions retournent un résultat (nombre, chaîne de caractères, etc.) que nous pouvons utiliser dans le programme principal.

Essayons d'écrire une procédure simple :
Supposons que nous voulions afficher la chaîne "Erreur" chaque fois qu'une erreur peut se produire dans le code en raison de la faute de l'utilisateur (par exemple, lorsqu'il saisit des données incorrectes)
Cela peut être fait en écrivant l'opérateur cout << "Erreur" ; Et maintenant, imaginez qu'une telle ligne doive être insérée à de nombreux endroits dans le programme. Bien sûr, vous pouvez simplement l'écrire partout. Mais cette solution a deux inconvénients.
1) cette chaîne sera stockée en mémoire plusieurs fois
2) si nous voulons changer la sortie en cas d'erreur, nous devrons changer cette ligne tout au long du programme, ce qui est plutôt gênant

Dans de tels cas, des procédures sont nécessaires.
Un programme avec une procédure pourrait ressembler à ceci : #include<iostream> en utilisant l'espace de noms std ; void printError() // description de la procédure { cout << "Erreur"; // corps de la procédure - commandes que la procédure exécutera } principal() { ... printError() // lance la procédure d'exécution. Nous spécifions simplement le nom de la procédure que nous voulons exécuter. ... impressionErreur() ... } La procédure commence par le mot void. Il y a des crochets vides après le nom de la procédure.
Toutes les instructions exécutées dans une procédure sont mises en retrait. 

Les procédures sont écrites avant la fonction principale main()

Pour exécuter une procédure, dans le programme principal, vous devez l'appeler par son nom et n'oubliez pas d'écrire des parenthèses !
Vous pouvez appeler une procédure dans un programme autant de fois que vous le souhaitez.

Imaginons maintenant que nous ayons besoin d'afficher différents messages en réponse à l'erreur d'un utilisateur, selon le type d'erreur qu'il a commise.
Dans ce cas, vous pouvez écrire votre propre procédure pour chaque erreur :   annuler printErrorZero() { cout << "Erreur. Division par zéro!"; } annuler printErrorInput() { cout << "Erreur de saisie !" ; } Et s'il y a beaucoup plus d'erreurs possibles ? Cette solution ne nous conviendra pas !
Nous devons apprendre à contrôler la procédure en lui indiquant quel message d'erreur afficher.
Pour cela, nous avons besoin de paramètres que nous écrirons entre parenthèses après le nom de la procédure annuler printError (chaînes) { cout << s ; } Dans cette procédure, s est un paramètre - une variable spéciale qui vous permet de contrôler la procédure.
Le paramètre est une variable qui détermine le fonctionnement de la sous-routine. Les noms des paramètres sont répertoriés séparés par des virgules dans l'en-tête du sous-programme. Le type de paramètre est écrit avant le paramètre.

Maintenant, lors de l'appel de la procédure, vous devez indiquer entre parenthèses la valeur réelle qui sera affectée au paramètre (variable s) à l'intérieur de notre procédure printError("Erreur ! Division par zéro !"); Cette valeur s'appelle un argument.
L'argument est la valeur du paramètre qui est transmise à la sous-routine lorsqu'elle est appelée.
Un argument peut être non seulement une valeur constante, mais également une variable ou une expression arithmétique.

Variables locales et globales
Il est souvent nécessaire d'utiliser des variables supplémentaires qui ne seront utilisées que dans le sous-programme. Ces variables sont appelées locales (ou locales) et ne peuvent être manipulées qu'au sein de la sous-routine dans laquelle elles sont créées.
 
La portée de la variable locale est le bloc entre accolades dans lequel elle est déclarée

Le programme principal en C++ est également un sous-programme, donc toutes les variables déclarées dans main() sont des variables locales.
Les autres sous-programmes ne "savent" rien des variables locales des autres sous-programmes.

Ainsi, il est possible de limiter la portée (portée) d'une variable uniquement au sous-programme où elle est vraiment nécessaire. En programmation, cette technique est appelée encapsulation  - empêcher une variable d'être modifiée de l'extérieur.

S'il est nécessaire de déclarer une variable qui serait visible n'importe où dans le programme (dans n'importe quel sous-programme), alors ces variables sont déclarées en dehors de tous les sous-programmes (voir le programme 3 du tableau ci-dessous).
Ces variables sont appelées globales.

En C++, au démarrage du programme, toutes les variables globales sont automatiquement mises à zéro (les variables booléennes prennent la valeur false).


Analysez trois programmes : s'affiche à l'écran
annuler le test() {   int je = 5 ; cout << je; }
annuler le test() {   int je = 5 ;   cout << je; } principal() { int je = 7 ;   cout << je;   test(); }
#include <iostream> en utilisant l'espace de noms std ; int je ; annuler le test() {   je = 2 ; } principal() { test(); cout << je; }
1) Dans ce programme, la variable i est locale. Une variable locale est déclarée dans une sous-routine 2) Ici, même s'il y a une variable i dans le programme principal (avec la valeur 7), une nouvelle variable locale i avec la valeur 5 sera créée. 
Lorsque vous exécutez ce programme, l'écran affichera la valeur 75
3) Ce programme a une variable globale i. Sa valeur peut être changée à l'intérieur d'un sous-programme, et à l'intérieur du programme principal
La procédure fonctionnera avec la variable globale i et lui attribuera une nouvelle valeur égale à 2. La valeur 2

Tâche
Écrivez une procédure qui échange les valeurs de deux variables.

Les particularités de cette tâche sont que nous avons besoin que les modifications apportées à la procédure soient connues du programme appelant.

Essayons d'écrire la procédure comme ceci : void Swap ( int a, int b ) // avec une telle description des paramètres de la procédure, { // les valeurs des arguments (x et y) seront copiées, entier c ; // les variables a et b sont des variables indépendantes non liées à x et y c = un ; un = b ; b=c ; } principal() { entier x=1, y=2 ; Échange(x, y); // les valeurs des variables x et y (arguments) sont copiées dans les paramètres a et b cout << "x=" << x<< ", y=" << y; //x=1, y=2 } Si vous exécutez ce programme, vous pouvez voir que les valeurs des variables x et y n'ont pas changé. Pour que les paramètres modifient les valeurs des arguments, vous devez utiliser passage de données par référence. Pour ce faire, après le nom du type de données dans l'en-tête du sous-programme, vous devez mettre le signe & ("esperluette"). void Swap ( int & a, int & b ) // maintenant les variables a et b obtiennent les adresses des variables x et y en mémoire { entier c ; c = un ; un = b ; b=c ; } Utilisation : Si vous passez un argument par référence, alors seul le nom de la variable (PAS un nombre et PAS une expression arithmétique) peut être à cet endroit lors de l'appel de la procédure !< br />
N'appelez PAS une procédure comme celle-ci : Échange(x, 4 ); Échange(5+x, y);