Les fonctions

Sommaire

Index

Introduction

Pour réussir à résoudre des problèmes complexes, il est nécessaire voire indispensable de les découper en plus petits problèmes plus simples.

Découper son programme en sous-ensembles d’instructions (des blocs de code) permet de faire cela.

Cela permet de structurer et réutiliser le code.

Pour cela, nous allons utiliser un “conteneur d’instructions” nommé, selon le contexte et les possibilités offertes:

Fonctions et procédures

Objectifs

Désignation

Distinction fonctions/procédures

En pseudo-code:

Dans de nombreux langages:

Pseudo-code

Rappel: Mémo Pseudo-codes

Déclaration de procédure

PROCEDURE identifiant_procedure(<liste des paramètres>)
       [<declarations parametres>]
       [<declarations locales>]
  DEBUT

       <instructions>

  FIN_PROCEDURE

Appel de procédure

identifiant_proc(param1, param2, ...)

Dans certains cas (omission des parenthèses):

identifiant_proc param1

Déclaration de fonction

FONCTION identifiant_procedure(<liste des paramètres>)
       [<declarations parametres>]
       [<declarations locales>]
  DEBUT

     <instructions>

     RETOURNE <valeur_de_retour>
  FIN

Valeur de retour

L’instruction suivante arrête l’exécution de la fonction:

RETOURNE <valeur_de_retour>

Appel de fonction

nom_variable = identifiant_fonc(param1, param2, ...)

ou (si la valeur de retour n’est pas utile)

identifiant_fonc(param1, param2, ...)

Exemples

Année bissextile

Algorithme annee_est_bissextile(annee)

On reprend l’algorithme permettant d’indiquer si une année est bissextile:

SI (annee MOD 4 == 0) ET (annee MOD 100 != 0 OU annee MOD 400 == 0) ALORS
    AFFICHER "Bissextile"
SINON
    AFFICHER "Non bissextile"
FIN_SI

Procédure indique_bissextile(annee)

Pour placer cet algorithme dans une fonction, on identifie les paramètres. Ici, un seul paramètre : l’année (annee)

PROCEDURE indique_bissextile(annee DE_TYPE entier)
  DEBUT
    SI (annee MOD 4 == 0) ET (annee MOD 100 != 0 OU annee MOD 400 == 0) ALORS
      AFFICHER annee & "est bissextile"
    SINON
      AFFICHER annee & "n'est pas bissextile"
    FIN_SI
  FIN_PROCEDURE

Fonction est_bissextile(annee)

Pour placer cet algorithme dans une fonction:

Comme l’élément à renvoyer est un booléen, il suffit de renvoyer la condition initialement placée dans la structure SI…ALORS…SINON

FONCTION est_bissextile(annee DE_TYPE entier)
  DEBUT
    RETOURNE (annee MOD 4 == 0) ET (annee MOD 100 != 0 OU annee MOD 400 == 0) 
  FIN_FONCTION

Tautologie alert

FONCTION est_bissextile(annee DE_TYPE entier)
  DEBUT
    SI (annee MOD 4 == 0) ET (annee MOD 100 != 0 OU annee MOD 400 == 0) ALORS
      RETOURNE VRAI
    SINON
      RETOURNE FAUX
    FIN_SI
  FIN_FONCTION

Adaptation de la procédure pour utiliser la fonction est_bissextile(annee)

La fonction peut être utilisée par la procédure afin de réutiliser le code.

Dans le cas suivant:

PROCEDURE indique_bissextile(annee DE_TYPE entier)
  DEBUT
    SI est_bissextile(annee) ALORS
      AFFICHER annee & "est bissextile"
    SINON
      AFFICHER annee & "n'est pas bissextile"
    FIN_SI
  FIN_PROCEDURE

Appeler des fonctions/procédures prédéfinies

Deux fonctions déjà utilisées

Trigonométrie

Utilisation

Pseudo-code

Par exemple si angle est une valeur flottante définie précédemment:

sin(angle)
Selon les langages
En Java
Math.sin(angle)
En Javascript
sin(angle)
En C
sin(angle)

Tableaux des fonctions mathématiques

Nom Pseudo-code Opérateur ou fonction (Java) (Javascript)
Sinus sin Math.sin Math.sin
Cosinus cos Math.cos Math.cos
Tangeante tan Math.tan Math.tan
Arc Sinus asin Math.asin Math.asin
Arc Cosinus acos Math.acos Math.acos
Arc Tangeante atan Math.atan Math.atan
Modulo modulo % %
Puissance puiss Math.pow **
Exponentielle exp Math.exp Math.exp

Exercices

Un peu de pratique avec du “pseudo-javascript”

Modèle pour pseudo-javascript

Copier le contenu ci-dessous dans un fichier nommé en fonction de l’exercice (par exemple: exercice-1.html):

<!DOCTYPE html>
<html>
<title>Modèle Algorithme</title>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<style>html{font-family: monospace;}</style>
<script type="text/javascript">
  /* NE RIEN ECRIRE ENTRE CETTE LIGNE ET LA LIGNE MARQUEE FIN*/
  /*DEBUT*/
  function _output_append(_text) {
    let output = document.getElementById('output');

    if(_text == " ") {
        output.innerHTML += "&nbsp;";
        }
        else {
            output.innerHTML += _text;
        }
    
  }
  function AFFICHER () {
    for(const arg of arguments) {
        if(arg == " ") {
            _output_append("&nbsp;") ;
        }
        else {
            _output_append(arg+" ") ;
        }
    }
    _output_append("\n");
  }
  function AFFICHER_SL () {
    for(const arg of arguments) {
        if(arg == " ") {
            _output_append("&nbsp;") ;
        }
        else {
            _output_append(arg) ;
        }
    }
  }
  function LIRE(message) {
    _output_append(message);
    var reponse = prompt(message, "");
    _output_append(reponse);
    return reponse
  }
  function LIRE_ENTIER(message) {
    _output_append(message);
    var reponse = parseInt(prompt(message, ""));
    _output_append(reponse);
    return reponse
  }
  function LIRE_FLOTTANT(message) {
    _output_append(message);
    var reponse = parseFloat(prompt(message, ""));
    _output_append(reponse);
    return reponse
  }
  function EST_NOMBRE(valeur) {
    return valeur != "" && !isNaN(valeur)
  }
  function CONVERTIT_EN_ENTIER(valeur) {
    return parseInt(valeur)
  }
  function CONVERTIT_EN_FLOTTANT(valeur) {
    return parseFloa(valeur)
  }
  function NON(booleen) {
    return ! booleen
  }
  ENTIER=parseInt
  ECRIRE=AFFICHER
  AFFICHE=AFFICHER
  NOMBRE_EST_INVALIDE=isNaN
  function LONGUEUR(tab) {
    return tab.length
  }
  /* NE RIEN ECRIRE ENTRE CETTE LIGNE ET LA LIGNE MARQUEE DEBUT*/
  /*FIN*/
</script>
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", (event) => {
  /*ECRIRE ICI VOTRE PROGRAMME*/



  
  /*FIN DU PROGRAMME*/
});
</script>
</head>
<body>
<blockquote style="border: solid rgb(168, 168, 168); "><code id="output"></code></blockquote>
</body>
</html>

Ouvrir le fichier correspondant dans un navigateur et observer le résultat.

Le programme est à modifier uniquement entre les lignes suivantes:

/*ECRIRE ICI VOTRE PROGRAMME*/

// Emplacement du programme à écrire

/*FIN DU PROGRAMME*/

N’y inscrivez pas les instructions telles que:

  AFFICHER("Bonjour")
  var reponse = ""
  while(NON(EST_NOMBRE(reponse))){ //TANT QUE
    reponse = LIRE("Saisir un nombre: ")
    n = ENTIER(reponse)
  }
  AFFICHER(n)

  if(n >= 0) {
    // ALORS
    AFFICHER("Positif")
  }

  if (n == 0) {
    // ALORS
    AFFICHER(n + " vaut zéro")
  }
  else  { //SINON
    AFFICHER("n différent de Zéro")
  }

  // ET Logique
  if (n > 0 && n % 2 == 0){
    AFFICHER(n, " est pair et positif")
  }

  // OU logique
  if (n == 1 || n == 2 || n == 4 || n == 8) {
    AFFICHER("n est une puissance de 2 inférieure à 10")
  }

  //SELON
  switch(n){
    case 1:
    case 2:
    case 4:
    case 8:
    AFFICHER("n est une puissance de 2 inférieure à 10 (SWITCH)")
  }


  // SELON
  switch(n){
    case 1:
        AFFICHER("Unité")
        //break;
    case 2:
      AFFICHER("Duo")
      //break;
    case 3:
      AFFICHER("Trio")
      //break;
    default:
      AFFICHER("autre valeur")
  }

  do { //FAIRE
    n = n - 1
    AFFICHER(n)
  } while(n >= 0) // TANT QUE


  while ( n < 4){// TANT QUE .. FAIRE
    n = n + 1
    AFFICHER("n : "+ n)
  }

  // POUR i ALLANT DE 0 À 10
  for( i = 0 /* i ALLANT DE 0*/ ; i <= 10 /* À  10 */ ; i = i + 1 /*PAS DE 1*/ ){
    AFFICHER("i = ", i)
  }

  /*POUR j ALLANT DE 1 à 2 PAS DE 1*/
  for( j = 1 ; j < 3 ; j = j + 1 ){
    AFFICHER("j = ", j)
  }

  function PROCEDURE1(a, b) {
    AFFICHER("a = ", a)
    AFFICHER("b = ", b)
  }

  PROCEDURE1(i, j)

  function CARRE(x) {
    return x * x
  }

  // Déclarer une variable
  let h = 7
  let carre_h = CARRE(h)
  AFFICHER(carre_h)



  AFFICHER_SL("-")
  AFFICHER_SL("-")
  AFFICHER_SL("-")
  AFFICHER_SL("-")
  AFFICHER("")

  /*FIN*/

L’opérateur d’affectation est le =

Ne déclarer les variables que sous cette forme:

let nom_variable = 0;

Est pair

Créer la fonction est_pair(nombre) qui renvoie VRAI si le nombre entier passé en paramètre est pair, FAUX sinon.

Écrire le programme principal permettant d’afficher si 2, 5, 8 et 13 sont pairs ou pas.

Exemple d’affichage

2 est pair
5 n'est pas pair

Pythagore

Créer la fonction puissance2 (qui calcule la valeur du carré du nombre passé en paramètre) pour écrire le calcul du carré de l’hypothénuse dans un triangle rectangle.

Utiliser la fonction racine(int) (parfois aussi nommée sqrt) qui prend un entier en paramètre et renvoie la valeur flottante de la racine carrée du paramètre.

Dans le programme principal, demander à l’utilisateur les valeurs des côtés et afficher la valeur de l’hypothénuse (arrondie à un chiffre après la virgule).

Fonctions textuelles

Traiter des chaînes de caractères

Une chaîne de caractères permet de représenter un texte.

Différentes fonctions, souvent intégrées aux langages de programmation, permettent de traiter, découper, analyser ce type de données.

Concaténation

L’opérateur de concaténation utilisé en pseudo-langage est le &

Ainsi le programme suivant:

txt <- "abc" & "def"
AFFICHER txt

Affichera:

abcdef

Longueur

La fonction LONGUEUR(chaine) renvoie la longueur de la chaîne passée en paramètre.

AFFICHER LONGUEUR("abc")

Affichera:

3

Sous-chaîne

La fonction sous_chaine(chaine, pos, nb) renvoie la longueur de la chaîne passée en paramètre, depuis la position pos (en partant de 0), et de longueur nb caractères.

AFFICHER sous_chaine("abcdefghi", 2, 3)

Affichera:

cde

Variantes de nom:

Position d’une sous-chaine: trouver(chaine, souschaine)

Renvoie un nombre correspondant à la position de souschaine dans chaine.

Si chaine ne contient pas souschaine, renvoie un nombre négatif (-1)

Exemples

AFFICHER(trouver("abcdefghi", "fgh"))
AFFICHER(trouver("abcdefghi", "cba"))

Affichera:

5
-1

Exercices (2)

Procédure afficher caractères

Créer une procédure afficher_n_car permettant d’afficher un certain nombre de fois le caractère choisi.

Paramètres:

Cette fonction sera à réutiliser dans les exercices qui suivent.

Triangle vide

Nom du programme: triangle_vide

Ecrire une procédure qui affiche un triangle rectangle sous forme de chaîne de caractères aligné à droite. Le triangle est représenté avec des points et seuls ses côtés sont affichés. L’angle droit du triangle est en haut à droite.

Le nombre de lignes est saisi par l’utilisateur

Données de test

Pour lignes = 6, l’affichage attendu est :

......
 .   .
  .  .
   . .
    ..
     .

Figures

Programme pyramideNombre

Écrire une procédure qui affiche une pyramide avec des nombres. Le sommet contient un élément (nombre 1). La base contient le nombre de lignes avec le nombre égal à lignes.

Le nombre de lignes est saisi par l’utilisateur

Données de test

Pour lignes = 5:

    1
   2 2
  3 3 3
 4 4 4 4
5 5 5 5 5

losange

Écrire une procédure qui dessine un losange avec des o. Le nombre de lignes indique le nombre de lignes dans la première moitié du losange.

Le nombre de lignes est saisi par l’utilisateur

Données de test

Pour lignes = 5:

    o
   ooo
  ooooo
 ooooooo
ooooooooo
 ooooooo
  ooooo
   ooo
    o

Fonctions textuelles

Nom du dossier dans le dépôt git: fonctions-textuelles

Fonction egales(chaine1, chaine2)

Écrire la fonction egales(chaine1, chaine2) qui vérifie si deux chaînes sont identiques.

En pseudo- JS, pour récupérer un caractère à un indice précis dans la chaîne, on utilise le code suivant (identique aux tableaux):

let chaine = "abcdefg"

AFFICHER(chaine[2])

On définirait donc la fonction caractereA(texte, index) qui renvoie le caractère situé à l’index index de la chaîne texte de la manière suivante:

function caractereA(texte, index){
    return 
}

Nom du fichier à publier: egales.js

Pour vérifier que votre fonction fonctionne correctement, utiliser le code ci-dessous

function egales(ch1, ch2){
  return true
}

/*----NE RIEN MODIFIER CI-DESSOUS------*/
function tester(t){
    let fonction = t.fonction
    let res = t.resultat
    if (fonction() == res){

      AFFICHER("SUCCES  : " + t.nom)
      return 1;
    } else {
      AFFICHER("ECHEC   : " + t.nom)
      return 0;
    }
}

function lance_tests(tests){
  let compteur = 0;
  let reussite = 0;
  for(const t of tests){
    reussite = reussite + tester(t);
    compteur = compteur + 1
  }
  return [reussite, compteur]
}

let res = lance_tests([
  {
    "fonction": function(){ return egales("ab", "cd") },
    "resultat": false,
    "nom":'egales("ab", "cd") renvoie false'
  },
  {
    "fonction": function(){ return egales("abcd", "abcd") },
    "resultat": true,
    "nom":'egales("abcd", "abcd") renvoie true'
  },
  {
    "fonction": function(){ return egales("", "abcd") },
    "resultat": false,
    "nom":'egales("", "abcd") renvoie false'
  },
  {
    "fonction": function(){ return egales("ab", "") },
    "resultat": false,
    "nom":'egales("ab", "") renvoie false'
  },
  {
    "fonction": function(){ return egales("", "") },
    "resultat": true,
    "nom":'egales("", "") renvoie true'
  },
]);

AFFICHER(res[0] + "/" + res[1])

Remplacer le code:

function egales(ch1, ch2){
  return true
}

Par celui de la fonction que vous avez écrite.

Fonction gauche(chaine, n)

Réécrire la fonction qui renvoie les n caractères situés à gauche du texte passé en paramètre.

Code de test: gauche-test-pseudo.js

Nom du fichier à publier: gauche.js

Fonction droite(chaine, n)

Réécrire la fonction qui renvoie les n caractères situés à droite du texte passé en paramètre.

Code de test: droite-test-pseudo.js

Nom du fichier à publier: droite.js

Fonction trouver(chaine, n)

Réécrire la fonction trouver(chaine, souschaine) qui renvoie un nombre correspondant à la position de souschaine dans chaine.

Code de test: trouver-test-pseudo.js

Nom du fichier à publier: trouver.js

Exemples

AFFICHER(trouver("abcdefghi", "fgh"))
AFFICHER(trouver("abcdefghi", "cba"))

Affichera:

5
-1