Ce chapitre résume les différences principales entre les modules (programme principal, fonctions, procédures) dans les différents langages de programmation que nous connaissons.
Modules
En Pascal et en langage algorithmique, nous distinguons programme principal, procédures et fonctions.
En C, il existe uniquement des fonctions. La fonction principale main se distingue des autres fonctions par deux qualités:
a) Elle est exécutée lors de l'appel du programme.
b) Les types du résultat (int) et des paramètres (void) sont fixés.
Définition des modules
En langage algorithmique, le programme principal, les fonctions et les procédures sont déclarés dans des blocs distincts. Il est interdit d'imbriquer leurs définitions. La définition du programme principal précède celle des fonctions et des procédures.
En Pascal, les définitions des modules peuvent être imbriquées; c.-à-d.: on peut définir des fonctions et des procédures localement à l'intérieur d'autres fonctions ou procédures.
En C, il est interdit de définir des fonctions à l'intérieur d'autres fonctions, mais nous pouvons déclarer des fonctions localement.
Variables locales
En Pascal et en langage algorithmique, nous pouvons déclarer
des variables locales au début des fonctions et des procédures.
En C, il est permis (mais déconseillé) de déclarer des variables locales au début de chaque bloc d'instructions.
Variables globales
En Pascal et en langage algorithmique, les variables globales sont définies au début du programme principal.
En C, les variables globales sont définies au début du fichier, à l'extérieur de toutes les fonctions. (Les variables de la fonction principale main sont locales à main.)
Passage des paramètres
En Pascal et en langage algorithmique, nous distinguons entre passage des paramètres par valeur et passage des paramètres par référence.
En C, le passage des paramètres se fait toujours par la valeur. Pour pouvoir changer le contenu d'une variable déclarée dans une autre fonction, il faut utiliser un pointeur comme paramètre de passage et transmettre l'adresse de la variable lors de l'appel.
Exemple comparatif
La fonction DIVI divise son premier paramètre A par son deuxième paramètre B et fournit le reste de la division entière comme résultat. Le contenu du paramètre A est modifié à l'intérieur de la fonction, le paramètre B reste inchangé. Le programme principal appelle la fonction DIVI avec deux entiers lus au clavier et affiche les résultats.
- Solution du problème en langage algorithmique
programme TEST_DIVI entier N,D,R écrire "Entrer nominateur et dénominateur : " lire N lire D en R ranger DIVI(N,D) écrire "Résultat: ",N," Reste: ",R fprogramme fonction DIVI (A, B): entier résultat: entier A donnée: entier B entier C en C ranger A modulo B en A ranger A divent B en DIVI ranger C ffonction (* fin DIVI *)
* Le paramètre A est transféré par référence: Il est déclaré par le mot-clef résultat au début de la fonction.
* Le paramètre B est transféré par valeur: Il est déclaré par le mot-clef donnée au début de la fonction.
* Le résultat de la fonction est affecté au nom de la fonction. Cette affectation doit se trouver à la fin la fonction.
* Dans un appel, il n'y a pas de différence entre la notation des paramètres passés par référence et ceux passés par valeur.
- Solution du problème en Pascal
program TEST_DIVI var N, D, R: integer function DIVI (var A: integer; B: integer):integer; begin DIVI := A mod B; A := A div B; end; begin write('Entrer nominateur et dénominateur : '); read(N); readln(D); R := DIVI (N, D); writeln('Résultat: ',N,' Reste: ',R ); end.
* Le paramètre A est transféré par référence: Il est déclaré par le mot-clef var dans l'en-tête de la fonction.
* Le paramètre B est transféré par valeur: Il est déclaré sans désignation spéciale dans l'en-tête de la fonction.
* Le résultat de la fonction est affecté au nom de la fonction. Cette affectation peut se trouver n'importe où dans la fonction.
* Dans un appel, il n'y a pas de différence entre la notation des paramètres passés par référence et ceux passés par valeur.
- Solution du problème en C
#include <stdio.h> main() { int DIVI(int *A, int B); int N, D, R; printf("Entrer nominateur et dénominateur : "); scanf("%d %d", &N, &D); R = DIVI (&N, D); printf("Résultat: %d Reste: %d\n", N, R); return 0; } int DIVI (int *A, int B) { int C; C = *A % B; *A /= B; return C; }
* Le paramètre A reçoit l'adresse d'une variable: Il est déclaré comme pointeur sur int.
* Le paramètre B reçoit la valeur d'une variable: Il est déclaré comme int.
* Le résultat de la fonction est retourné à l'aide de la commande return. Comme l'exécution de la fonction s'arrête après la commande return, celle-ci doit se trouver à la fin de la fonction.
*
Dans un appel, le premier paramètre est une adresse. Le nom de la
variable N est donc précédé par l'opérateur adresse
&.
Le deuxième paramètre est passé
par valeur. Le nom de la variable est indiqué sans désignation
spéciale.
Vu de plus près, les trois langages offrent les mêmes mécanismes pour le passage des paramètres, mais:
>> en C nous devons veiller nous-mêmes à opérer avec les adresses et les pointeurs respectifs si nous voulons changer le contenu d'une variable déclarée dans une autre fonction;
>> en langage algorithmique et en Pascal, les mêmes opérations se déroulent derrière les rideaux, sous l'étiquette 'passage par référence' ('call-by-reference').