Sommaire

Les sous-programmes

1. Introduction

Problème

Nous disposons d'une urne contenant n billes numérotées et nous souhaitons effectuer p tirages sans remise depuis cette urne.

Le nombre de combinaisons possibles est calculé à l'aide de la formule :

C(n, p)

On demande d'écrire un programme en pascal qui saisit deux entiers n et p, avec (0 ≤ p ≤ n ≤ 12), puis calcule et affiche le nombre de combinaisons de p parmi n.

Solution

Début combinaisons
Répéter
  Ecrire("Donner n [0, 12] : ")
  Lire(n)
Jusqu'à (n dans [0..12])

Répéter
  Ecrire("Donner p [0, ", n, "] : ")
  Lire(p)
Jusqu'à (p ≥ 0) et (p ≤ n)

{ Calcul de n! }
fn ⟵ 1
Pour i de 1 à n Faire
  fn ⟵ fn * i
Fin pour

{ Calcul de p! }
fp ⟵ 1
Pour i de 1 à p Faire
  fp ⟵ fp * i
Fin pour

{ Calcul de (n-p)! }
fnp ⟵ 1
Pour i de 1 à (n-p) Faire
  fnp ⟵ fnp * i
Fin pour

cnp ⟵ fn div (fp * fnp)

Ecrire("C(", n, ", ", p, ") = ", cnp)

Fin combinaisons

Remarques

La solution donnée présente quelques inconvénients :

Une autre idée de solution

La solution donnée peut être améliorée en utilisant des modules pour éviter les répétitions dans certaines portions de code et, du même coup, améliorer la lisibilité du programme.

Les modules sont, aussi, le moyen recommandé pour la décomposition d’un problème compliqué en des sous-problèmes plus facile à résoudre.

Les modules sont aussi appelés sous-programmes. En algorithmique et en Pascal on distingue deux types de sous-programmes : les procédures et les fonctions.

Dans la suite de ce chapitre nous commencerons par présenter les fonctions et les procédures. Nous continuerons, la suite du chapitre, avec le type des paramètres et leurs modes de passage. Et nous terminerons par présenter un exemple d’analyse modulaire.

2. Les fonctions

a. Définition

Une fonction est un sous-programme qui renvoie un seul résultat en fonction de ses paramètres. Les paramètres d’une fonction sont, généralement, transmis par valeur.

Activité 1

Écrire une fonction qui renvoie la valeur de f(x) pour la fonction : f(x) = 3.x²-4.x+1

{En algorithmique}
DEF FN f(x:réel):réel
f ⟵ 3*x*x-4*x+1
Fin f
{En Pascal}
function f(x:real):real;
begin
  f := 3*x*x-4*x+1;
end;

3. Les procédures

a. Définition

Une procédure est un sous-programme qui ne renvoie aucun résultat. Les paramètres d’une procédure sont transmis soit par valeur, soit par variable.

Lorsque les paramètres d’une procédure sont passés par variable, elle peut les changer.

Il est, donc, possible d’exploiter cette propriété pour renvoyer un ou plusieurs résultats au programme appelant.

Activité 2

Écrire une procédure permettant de saisir une valeur comprise entre 20 et 30.

{En algorithmique}
DEF PROC SaisieValeur(var n: entier)
Répéter 
  Ecrire("Donner n [20, 30] :")
  Lire(n)
Jusqu’à (n ≥ 20) et (n ≤ 30)
Fin SaisieIntervalle
{En Pascal}
Procedure SaisieValeur(var n : integer);
begin
  Repeat 
    Write('Donner n [20, 30] :');
    Readln(n);
  Until (n >= 20) and (n <= 30);
end;

4. Paramètres et Modes de passage

Un sous-programme défini réellement un ensemble de traitements effectués sur des données. Ces données doivent être passées au sous-programme dans ses paramètres.

a. Types de paramètres

On distingue deux types de paramètres :

Exemples

{Paramètres formels}
DEF PROC Permuter(var a, b : entier)
aux ⟵ a
a ⟵ b
b ⟵ aux
FIN Permuter
{Paramètres effectifs}
Pour i de 1 à n-1 Faire
  Pour j de 1 à n-1 Faire
    Si t[i]>t[i+1] Alors
      Proc Permuter(t[i], t[i+1])
    Fin Si
  Fin Pour
Fin Pour

b. Modes de passages des paramètres

Il existent deux modes de passage des paramètres : par variable ou par valeur.

c. Passage par valeur

Lors d’un passage par valeur, la valeur de l'expression passée en paramètre est copiée dans une variable locale. C'est cette variable qui est utilisée pour faire les traitements dans le sous-programme appelé.

Exemples

{Dans une fonction}
DEF FN U(n:entier):réel
U ⟵ n*(n+1)/2
Fin U
{Dans une procédure}
DEF PROC Afficher(a, b : entier)
 Ecrire(a, "+", b, "=", (a+b))
Fin Afficher

d. Passage par variable

Le passage par variable consiste à passer les variables elles-mêmes. Toute modification du paramètre dans la fonction appelée entraîne, alors, la modification de la variable passée en paramètre.

Remarque : Bien qu’il soit possible d’utiliser le mode de passage de paramètres par variable avec les fonctions, il est fortement recommandé de l’éviter et ce pour des raisons pédagogiques.

Exemples

DEF PROC Incrementer(var n:entier;
                     pas:entier)
  n ⟵ n + pas
Fin U
DEF PROC Remplir(n : entier; 
                 var t : tab)
  Pour i de 1 à n Faire
    t[i] ⟵ Alea(50) + 1
  Fin Pour
Fin Afficher

5. Décomposition Modulaire

a. Problème

Nous disposons d'une urne contenant n billes numérotées et nous souhaitons effectuer p tirages sans remise depuis cette urne.

Le nombre de combinaisons possibles est calculé à l'aide de la formule :

C(n, p)

On demande d'écrire un programme en pascal qui saisit deux entiers n et p, avec (0 ≤ p ≤ n ≤ 12), puis calcule et affiche le nombre de combinaisons de p parmi n, en utilisant une approche modulaire.

b. Pré-analyse

Le problème peut être décomposé comme suit :

Préanalyse

La résolution du problème se réduit, maintenant, à l’écriture des sous-programmes présentés dans la figure ci-dessus.

c. Solution

Programme principal

{P.P}
Résultat = Ecrire("C(", n, ", ", p, ") = ", c)
c ⟵ fn cnp(n, p)
n = Proc Saisie(n, 12)
p = Proc Saisie(p, n)
Fin PP
TDO
Objet Type/Nature
n, p, c entier

Procédure Saisie

DEF PROC saisie(var n : entier; max : entier)
  Répéter
    Ecrire("Donner un entier [0, ", max, "] : ")
    Lire(n)
  Jusqu'à (n ≥ 0) et (n ≤ max)
Fin Saisie
TDO
Objet Type/Nature
   

Fonction cnp

DEF FN cnp(n, p : entier): entier
  cnp ⟵ fn fact(n) div (fn fact(p) * fn fact(n-p))
Fin cnp
TDO
Objet Type/Nature
   

Fonction fact

DEF FN fact(n : entier): entier
  f ⟵ 1
  Pour i de 2 à n faire
    f ⟵ f * i
  Fin Pour
  fact ⟵ f
Fin cnp
TDO
Objet Type/Nature
f, i entier

Remarque : Les variables utilisées dans un sous-programme sont appelées des variables locales, elles sont définies uniquement à l’intérieur du sous-programme.

Traduction en Pascal

program combinaisons;

procedure Saisie(var n : integer; max : integer);
begin
  repeat
    Write('Donner un entier [0, ', max, '] : ');
    Readln(n);
  until (n >= 0) and (n <= max);
end;

function fact(n : integer):longint;
var i : integer;
    f : longint;
begin
  f := 1;
  for i:=2 to n do f := f * i;
  fact := f;
end;

function cnp(n, p : integer):longint;
begin
  cnp := fact(n) div (fact(p) * fact(n-p));
end;

var n, p : integer; c : longint;
begin
  Saisie(n, 12);
  Saisie(p, n);
  c := cnp(n, p);
  Writeln('C(', n, ', ', p, ') = ', c);
  Readln;
end.