précédent sommaire accueil suivant
Vos suggestions au : webmaster@debutantprogjava.com
Vos suggestions au : webmaster@debutantprogjava.com

B.1 Comment et pourquoi et pourquoi écrire une fonction ?

Immaginez un programme informatique dans lequel il arrive qu' on écrive un ensemble d' instructions de 10 lignes (parfois bien plus). Imaginez ensuite que cet ensemble d' instructions se retrouvent jusqu' à 10 fois (parfois, bien plus) dans le même programme. Parce qu' on veut exécuter 10 fois ces instructions. On a donc 100 lignes rien que pour cet ensemble d' instructions. Si ce n' est que ça, pas bien grage me direz-vous. Un copier-coller résoudra le problème en 2 temps, 3 mouvements.
Imaginez maintenant que pour une raison quelconque, vous ayez envie de changer l' une (peut-être même plus) des lignes de cet ensemble d' instructions. Vous serez bien obligé de faire ça une dizaine de fois. Sur un programme informatique de plus de 1 000 lignes par exemples, il faudra les trouver ces instructions à changer. Même si votre programme est le plus aéré et le plus commenté (des lignes de commentaires) possible, ce ne sera pas de tout repos. Et je me limite à un ensebles de 10 instructions 10 fois. Cela pourrait prendre des porprtions insoupçonnées dans un grand logiciel commercial tel qu' un navigateur Internet ou le logiciel de gestion des vols d' une grande compagnie aérienne ou de gestion du personnel d' une multi nationale tel que Google. Si vous êtes débutants en programmation, vous n' avez même pas idée de l' importance d' un grand logiciel. Ne soyez pas étonné qu' on vous parle de 50 000 lignes de code.
La maintenance de ce logiciel peut rapidement devenir un travail de titan.

C' est pourquoi l' écriture des fonctions est primordiables en programmation. Par exemple, vous regroupez les 10 lignes (ou plus) d' instructions dans une fonction. Puis vous utilisez simplement le nom de la fonction pour exécuter les 10 lignes. Exemple : lorsque vous écrivez int a = Math.sqrt(b); . Vous untilisez une seule ligne pour invoquer la fonction Math.sqrt(). Mais dans la définition de cette fonction, combien de lignes utilisées.Ici, on n' en sait rien. c' est une fonction prédéfinie par les créateurs de Java. On ne connaît pas le code. Et lorsqu' il s' agit de changer quelques intructions, vous changez simplement ces quelques instructions que vous trouvez plus aisément grâce à la déclaration de la fonction. Pas besoin de regarder parmi les 10 000 lignes de code pour changer 10 fois ces instructions.

Vous comprendrez mieux dans la 2ème partie des écritures de fonctions lorsque nous allons traiter 3 grands projets. Car l' écriture des premières fonctions trop simples) ne vous fera pas voir leur importance. Il s' agit d' abord d' apprendre à les écrire

En attendant, commençons par voir comment écrire une fonction.

Rappel : Je fais encore une erreur de temps en temps en parlant de fonction au lieu de parler de méthode. Ce n' est pas encore très grave. En Programmation orientée Objet, on parlera exclusivement de méthode. Une fonction fournit toujours un résultat. Lorsque ce n' est pas le cas, on utilise le mot méthode. Une fonction est forcément une méthode. La réciproque n' est pas vraie.

EXERCICE 1

Ecrivons une fonction f qui, à tout nombre réel x, associe un nombre réel y = x2. Donc son carré

CORRECTION 1
En mathématiques, on écrira : 

f : R --> R
    x --> y = x2

En java, on fera :

1.     public static double f(double x)
2.     {
3.          double y = x * x;
4.          return y;
5.     }	

En maths, R, ensemble de départ. R, ensemble d' arrivée. x appartient à R et y appartient R. R étant l' ensemble des nombres réels.

En java, lorsqu' on écrit une fonction ou une méthode, on commence par la déclarer. Voir ligne 1. Généralement, on déclare une méthode à l' aide de 4 mots.
Le premier mot = public ou private ou protected. En P.O.O on utilisera l' un des trois mots. Surtout les deux derniers. Tant qu' on n' est pas en P.O.O (programmation orientée objet), contentez-vous du mot public.
Ensuite, le deuxième mot est : static. En P.O.O, ce mot disparaît ou presque. En P.O.O, très peu de méthodes contiennent dans leur déclaration le mot static. Je vous expliquerais mieux pourquoi le mot static lorsqu' il s' agira de ne plus l' utiliser. Donc, en P.O.O.
Le troisième mot est le type du résultat fournit par la méthode.
Le quatrième mot de la déclaration d' une méthode est forcément le nom de la méthode. Ici, la méthode s' appelle f.

Lorsque nous avons utilisé les méthodes prédéfinies (Notament, celles des classes Math et String), je vous ai parlé des méthodes qui fournissent un résultat et celles qui n' en fournissent pas. Lorsqu' une méthode fournit un résultat, la dernière instruction de sa définition est forcément return resultat; resultat étant le nom de la variable dont le contenu est le résultat fournit pas la méthode. La définition d' une fonction, c' est l' ensemble des instructions de cette méthode. C' est donc l' ensemble des instructions qu' on voit entre les accolades (ouverte et fermée) qu' on voit en dessous de la déclaration de cette méthode. Ici, la méthode f a comme définition, les lignes 3 et 4.

Revenons à la déclaration de la méthode. Le nom de la méthode est toujours suivie des parenthèses à l' intérieur desquelles on met on déclare les paramètres éventuels.
PRECISONS :
La déclaration d' une variable est toujours suivie d' un point virgule. Exemple : int a; Pas celle d' une méthode. ligne 1
La déclaration des variables, paramètres d' une méthode, n' est jamais suivie de point virgule.
Les paramètres d' une méthode sont appelés les arguments ou paramètres muets. Muet parce qu' il n' y a pas de valeur. Tout comme on a écrit f en mathématiques, il n' y a pas eu de valeur. On utilise des valeurs lorsqu' on veut l' image de x. Par ex, f(2.5) = 6.25
En java, j' utilise la fonction f en mettant son résultat dans une variable. Ex : double a = f(2.5); f(2.5) fournit la valeur 6.25. La variable a est ainsi affectée de la valeur 6.25.
Le nombre d' arguments d' une méthode peut être égal à zéro. Ce n' est pour ça qu' on supprimera les parenthèses. Le nom d' une méthode doit doit toujours être suivi des parenthèses. Même lorsque l' on ne déclare pas la méthode. Par exemple, la méthode main() contient toutes les instructions d' un programme.

Lorsqu' une méthode ne fournit aucun résultat, le troisième mot est void. Ce mot est anglais et veut dire vide. Mais prend surtout le sens de rien en programmation. La méthode ne fournit rien, donc, void.

Autre chose : En math, R est l' ensemble des nombres réels. EN java, c' est le type double ou float. Mais quand on ne sait pas lequel choisir, on prend double par défaut.

On dit aussi que le type de la variable retournée est aussi le type de la méthode. Ainsi, la méthode main() est toujours de type void. D' où la déclaration : public static void main(String [] args).

*********************

EXERCICE 2

Ecrire une fonction qui à tout couple de nombres réels (x, y), associe le nombre réel z = xy. Le profuit de x par y.

CORRECTION  2
En mathématiques, on écrira : 

f : R x R --> R
    (x, y) --> y = xy

En java, on fera :

1.     public static double f(double x, double y)
2.     {
3.          double z = x * y;
4.          return z;
5.     }	

Si j' utilise cette fonction dans la méthode main() par exemple, je ferais : double a = f(2.2, 3.1); Et la valeur 6.82 sera affectée à la variable a.
Conseil : Donnez toujours à votre méthode, un mot significatif. Un mot qui donne des indications sur ce que fait la méthode. Sur les deux premiers exempls, j' ai voulu passer des maths à la programmation.

Autre notion de vocabulaire. Lorsqu' on dit qu' une méthode fournit un résultat, on peut aussi dire que la méthode renvoie un résultat ou encore que la méthode retourne un résultat. C' est le mot retourner qui est d' ailleurs utilisé en java. Le mot clé return veut justement dire retourner.

*********************

EXERCICE 3

Ecrire une méthode qui étant donné les deux côtés (adjacent et opposé) d' un triangle rectangle, retourne son hypothénuse.

CORRECTION 3

1.     public static double hypothenuse(double adjacent, double oppose)
2.     {
3.          double hypot = Math.sqrt( (adjacent * adjacent) + (oppose * oppose) );
4.          return hypot;
5.     }

Vous vous souvenez certainement du fameux théorème de pythagore : Dans un triangle rectangle, le carré de l' hypothénuse est égale à la somme des carrés des 2 autres côtés. Donc l' hypothénuse est égale à la racine carré des la somme des carrés des 2 autres côtés.

Les arguments sont donc les 2 côtés. Et le résultat fourni (renvoyé, retourné) est donc l' hypothénuse).

*********************

EXERCICE 4

Ecrire une méthode qui étant donné un nombre réel, renvoie sa valeur absolue

CORRECTION 4

1.     public static double valeurAbsolue(double a)
2.     {
3.          if( a > 0)
4.          {
5.               return a;
6.          }
7.          else
8.          {
9.               return -a;
10.         }
11.    }

Avant toute chose, sachez que vous n' avez pas besoin d' écrire une méthode qui existe déjà. Et la méthode qui retourne la valeur absolue d' un nombre réel existe déjà. C' est la méthode abs() de la classe Math. Vous vous souvenez ? Sinon, regardez par ici

Si j' ai voulu écrire cette méthode, c' est pour vous montrer qu' on peut avoir dans une méthode, 2 instructions return. Mais attention, ça ne veut pas dire qu' une méthode peut retourner 2 valeurs. Jamais, jamais, jamais. Une méthode retourne toujours une et une seule valeur. Mais comme vous pouvez le voir, les 2 instructions sont dans une structure conditionnelle. La valeur absolue de a sera a si a est positif et -a dans le cas où a est négatif. Donc, en fin de compte, une seule valeur sera retournée.

Bien entendu, les méthodes ne sont pas toutes de type double avec des arguments de type double. A partir de maintenant, nous allons varier les plaisirs.

*********************

EXERCICE 5

Ecrire une méthode qui, étant donné un tableau de nombres entiers et un nombre entier quelconque, teste la présence de ce nombre dans ce tableau.

Lorsque vous verrez un exercice sur les méthodes avec les mots teste, ou vérifie, ou permet de savoir si, sachez que vous avez affaire une méthode de type booléen. Mais attention, ne vous concentrez pas sur ces mot ou expressions pour dire qu' une méthode est de type booléenne. Il s' agit surtout de réfléchir un peu en se posant la question suivante. L' énoncé de l' exercice pose-t-elle une question à laquelle il faut forcément répondre par vrai ou par faux ? Si c' est le cas, alors, la méthode est de type booléenne.

Ici, l' énoncé permet de se poser la question suivante : Ce nombre entier est-il dans le tableau de nombres entiers ? Réponse = vrai ou faux.
Donc, méthode de type booléenne. Et le type booléen en java utilise le mot clé boolean.

1.     public static boolean nombreDansTableau(int a, int [] tab)
2.     {
3.          boolean verite = false;
4.          for(int i = 0; i < tab.length; i++)
5.          {
6.               if(tab[i] == a)
7.               {
8.                    verite  = true;
9 .                   break;
10.               }
11.         }
12.         return verite;         
11.    }

Lorsque nous devons écrire une méthode booléenne, nous devons définir une variable booléenne. Le type d' une méthode c' est le type de la valeur fournie (renvoyée, retournée). Donc, dans la définition d' une méthode, nous devons définir une variable booléenne : ligne 3. Je l' ai initialisée à false pour une raison que j' indique ci-dessous.
Puis je parcours le tableau du premier au dernier élément (ligne 4). En disant que si l' élément actuel a la même valeur que la variable a, alors verite (variable bolléenne) est égale à true. Puisque effectivement, cela veut dire que la réponse à la question qu' on se pose est :Vrai Et dans ce cas, on sort de la boucle (break, ligne 9). Puisque si on a trouvé au moins un élément du tableau dont la valeur est celle de a, il est inutile de comparer a avec les autres éléments. Raison pour laquelle on initialise à false. Ainsi, on n' est pas obligé de parcourir tout le tableau, au cas où on trouve avant la fin, un élément qui correspond.
Puis on retourne la variable bolléenne verite..

C' est bien beau de savoir écrire une méthode. Mais encore faut-il savoir l' utiliser. On peut utiliser une méthode dans la méthode main() Cas le plus fréquent. Mais on peut aussi l' utiliser dans une autre méthode. Commençons d' abord par utiliser les méthodes écrites ci-dessus dans une méthode main()

1.     public class TesterMethodes
2.     {
3.          public static void main(String [] args)
4.          {
5.               System.out.println("Le carré de 5.0 = " + carre(5.0));
6.               System.out.println();
7.               double a = carre(6.0);
8.               System.out.println("le carré de 6 = " + a);
9.               System.out.println();
10.              int x = 12;
11.              System.out.println("le carré de x = " + carre(x));
12.              System.out.println();
13.              double p = f(5.2, 3);
14.              System.out.println("le produit de 5.2 par 3 = " + p);
15.              System.out.println();
16.              System.out.println("valeur absolue de - 9 = " + valeurAbsolue(- 9));
17.              System.out.println();
18.              double adjacent = 4.0, oppose = 3.0;
19.              System.out.println("hypothénuse si les 2 autres côtés sont 4 et 3 = " + hypothenuse(4.0, 3.0));
20.              System.out.println();
21.              int nombre = 5;
22.              int [] tab = {2, 6, 5, 9, 11};
23.              System.out.println(nombreDansTableau(nombre, tab));
24.         }
25.    
26.         //méthode permettant de fournir le carré d 'un nombre réel
27.         public static double carre(double x)
28.         {
29.              double y = x * x;
30.              return y;
31.         }
32.     
33.         // méthode permettant de fournir la produit de deux nombres réels
34.         public static double f(double x, double y)
35.         {
36.              double z = x * y;
37.             return z;
38.         }
39.         // méthode permettant de fournir la valeur absolue d' un nombre réel
40.         public static double valeurAbsolue(double a)
41.         {
42.              if( a > 0)
43.              {
44.                   return a;
45.              }
46.              else
47.              {
48.                   return -a;
49.              }
50.         }
51.         //méthode permettant de fournir l' hypothénuse d' un triangle rectangle.
52.         public static double hypothenuse(double adjacent, double oppose)
53.         {
54.              double hypot = Math.sqrt( (adjacent * adjacent) + (oppose * oppose) );
55.              return hypot;
56.         }
57.
58.         // méthode permettant de vérifier la présence d' un nombre entier dans un tableau de nombres entiers.
59.         public static boolean nombreDansTableau(int a, int [] tab)
60.         {
61.               boolean verite = false;
62.               for(int i = 0; i < tab.length; i++)
63.               {
64.                   if(tab[i] == a)
65.                   {
66.                        verite  = true;
67.                        break;
68.                   }
69.               }
70.               return verite;         
71.         }
72.    }

Lorsque vous écrivez une méthode dans la classe contenant la méthode main(), je vous conseillerais de mettre cette méthode sous la méthode main(). Ce n' est pas une obligation. Mais je trouve logique de voir d' abor main() puisque c' est elle contient toutes les instructions du programme.
Je vous rappelle que lorsqu' on utilise une fonction dans la classe où elle est définie, on invoque tout simplement le nom de la méthode. Lorsqu' on utilise une méthode, on dit qu' on appelle cette méthode. Ainsi, j' appelle sur la ligne 5, la méthode carre() déclarée ligne 27. Il existe diverses façons d' appeler une méthode.
L' expression carre(5.0) représente la valeur 25.0 parce que la méthode carre() retourne le carré de la valeur qui se trouve dans ses parenthèses. C' est pourquoi vous verrez à l' affichage : le carre de 5.0 = 25.0
L' expression double a = carre(6.0); signifie mettre 36.0 (représenté par l' expression carr(6.0) dans la variable a. C' est pourquoi vous verrez à l' affichage : le carre de 6.0 = 36.0
L' expression carre(x) veut dire, prendre la valeur de x (ici = 12, ligne 10), puis calculer son carré grâce à la méthode carre(). C' est pourquoi vous verrez à l' affichage : le carre de x = 144.0
Utilisez le même raisonnement pour compredre les autres lignes de code jusqu' à ligne 19.
Pour la méthode de type booléenne nombreDansTableau(), c' est encore le même raisonnement. Sauf qu' ici, ce n' est pas un nombre qui s' affiche. Plutôt la valeur true. Puisque la méthode retourne une valeur booléenne. Vous voyez bien que la valeur 5 se trouve bien dans le tableau.

Exercice à faire. Changer la valeur de nombre en donnant par exemple la valeur 55. Vous verrez afficher false parce que 55 n' est pas une valeur du tableau

*********************

EXERCICE 6

Ecrire une méthode qui, étant donné une chaine de caractères et un caractère quelconque, teste la présence de ce caractère dans ce tableau.

CORRECTION 6

1.     public static boolean caractereDansChaine(String chaine, char c)
2.     {
3.          boolean verite = false;
4.          for(int i = 0; i < chaine.length(); i++)
5.          {
6.               if(chaine.charAt(i) == c)
7.               {
8.                    verite = true;
9.                    break;
10.              }
11.          }
12.         return verite;
13.    }

C' est du déjà vu non ? Je déclare ma variable booléenne avant la boucle. Car une variable déclarée dans la boucle disparaît en sortie de boucle. Or c' est la variable à retourner. Puis je parcours la chaine pour voir si un caractère en position i de la chaine correspond au caractère. Si c' est oui, verite = true. Puis on sort aussitôt de la boucle dès qu' on trouve ce caractère. Si ce n' est pas le cas, la valeur reste à false comme déclarée. L' intérêt d' initialiser la variable à false vient de ce que on est pas obliger de faire le else après le if. Puisque le else correspond déjà à la situation où cette valeur est false.

Rappel : La méthode charAt() de la classe String renvoie le caractère dont la position dans la chaine est représentée par le nombre entier dans les parenthèses. chaine.charAt(2) est le caractère situé en position 2 de chaine. Autrement dit, le troisième caractère du contenu de la variable chaine.

Rappel : Les valeurs booléennes (true ou false) ne sont pas faites pour être affichées. On utilise leur existence surtout dans des structures conditionnelles if...else.

*********************

EXERCICE 7

Copiez la méthode caractereDansChaine() ci-dessus et collez là dans la classe TesterMethodes ci-dessus. Puis dans la méthode main(), collez le code ci-dessous après la ligne 23 de cette classe.

CORRECTION 7
char t = 'N'; String nom = "KENNEDY";
if(caractereDansChaine(nom, t))
{
	System.out.println("Le caractere " + t + " se trouve bien dans " + nom);
}
else
{
    System.out.println("Le caractere " + t + " ne se trouve pas dans " + nom);
}

Compilez puis exécutez. Vous verrez afficher : Le caractere N se trouve bien dans KENNEDY

Ensuite, changez 'N' en 'n'. Vous verrez afficher Le caractere n ne se trouve pas dans KENNEDY

Ce qui est normal. Le langage java est sensible à la casse. Il fait la différence entre majuscule et minucule. n est différent de N

L' expression caractereDansChaine(nom, t) représente la valeur true si la valeur de la variable t (ici, 'N') se trouve bien dans la valeur de la variable chaine (ici, KENNEDY). Cette valeur est alors true.

IMPORTANT !
Lorsqu' on utilise une méthode définie avec deux arguments, on l' utilise en y mettant deux valeurs dont les types correspondent à ceux des arguments.

Exemple : La méthode caractereDansChaine() a été définie (exercice 6) avec 2 arguments : le premier, un variable de type String et le deuxième, une variable de type char. Donc, quand je l' utilise (l' appelle), je respecte l' ordre et la nature des valeurs. Regardez CORRECTION 7 de l' EXERCICE 7 : if(caractereDansChaine(nom, t)). nom est de type String et t est de type char. Si je m' amuse à faire : if(caractereDansChaine(t, nom)) Message d' erreur à la compilation.

Autant on a l' obligation absolue de respecter l' ordre des arguments. L' obligation de respecter la nature est plutôt relative. En effet, je vous ai déjà dit qu' en Java, il existe la notion de conversion implicite. Si une méthode requiert comme argument, une variable de type double, vous pouvez utiliser byte, short, int, long et float. Car ces types sont tous convertibles implicitement en double.

*********************

EXERCICE 8

Ecrire une méthode permettant d' afficher un menu. N' importe lequel. Choisissez les thèmes.

CORRECTION 8

1.     public static void afficheMenuBanque()
2.     {
3.          System.out.println("Que voulez-vous faire ? ");
4.          System.out.println();
5.          System.out.println("1. Retrait avec ticket.     2. Retrait sans ticket");
6.          System.out.println("3. Consultation Solde.      4. Historique");
7.          System.out.println("5. Dernières opérations.    6. Autre");
8.     }

Il me semble que toute personne ayant utilisé une carte de crédit a vu quelque chose de similaire. Pas forcément la même chose bien sûr. Lorsque une méthode est de type void, elle ne renvoie (retourne, fournit) aucune valeur. On ne peut donc pas s' amuser à écrire a = afficheMenuBanque(); Quelque soit le type de a. Puisqu' il n' y a pas de return, rien se sera affectée à la variable a. Pire, y aura même afficha d' un message d' erreur.
Ici, il n' y a pas non plus d' argument. Donc, on n' utilise pas la méthode en y mettant quelque chose. Message d' erreur aussi si on tente d' y mettre une valeur.
Comment appelle-t-on (utilise-t-on) une méthode de type void ? On écrit simplement le nom de la méthode. Ici, il suffit d' écrire : afficheMenuBanque(); Et le tour est joué. Il s' affiche alors le menu décrit dans la définition de la méthode.

Attention : une méthode de type void ne possède pas forcément zéro arguments.

*********************

EXERCICE 9

Ecrire une méthode qui, étant donné un tableau de chaines, affiche chacune des valeurs sur une ligne valeurs

CORRECTION 9

1.     public static void afficheTableau(String [] tab)
2.     {
3.          for(int i = 0; i < tab.length; i++)
4.          {
5.               System.out.println(tab[i]);
6.          }
7.     }

Vous voyez ? Pour utiliser cette méthode, il suffit d' écrire : afficheTableau(nom)
nom étant le nom de la variable tableau dont on cherche à afficher les valeurs. Autre exemple.

*********************

EXERCICE 10

Ecrire une méthode qui, étant donné un tableau d' entiers, affiche les valeurs du tableau sur la même ligne

CORRECTION 10

1.     public static void afficheTableau(int [] tab)
2.     {
3.          for(int i = 0; i < tab.length; i++)
4.          {
5.               System.out.print(tab[i] + " ");
6.          }
7.     }

Pour utiliser cette méthode, il suffit d' écrire : afficheTableau(ent)
ent étant le nom de la variable tableau dont on cherche à afficher les valeurs. Dans ce genre d' exercice, afficher sur une même ligne les valeurs d' un tableau oblige à utiliser System.out.print() plutôt que sa variante avec ln à la fin. Et je suis sûr que vous avez compris pourquoi.

Vos suggestions au : webmaster@debutantprogjava.com
Vos suggestions au : webmaster@debutantprogjava.com
précédent sommaire accueil suivant
Cours de java - java pour débutant - programmation java - cours de programmation java - débutant en programmation
.....