Activité : Structures de contrôle

Consigne

Durant les 45 prochaines minutes, votre tâche est de réaliser et d’exécuter à l’aide du débogueur une série de petits programmes qui doivent vous permettre de découvrir l’effet de différentes structures de contrôle.

Une structure de contrôle est une instruction dont le rôle est de contrôler le chemin du fil d’exécution (thread) du programme. Vous connaissez déjà une structure de contrôle. En effet, la structure de contrôle que l’on appelle « séquence » consiste simplement à écrire plusieurs instructions l’une à la suite de l’autre pour qu’elles soient exécutées dans l’ordre.

Durant cette activité, vous allez étudier trois nouvelles structures de contrôles :

  1. La structure de choix qui permet de choisir entre deux séquences d’instructions selon qu’une condition est remplie ou non.
  2. La structure de boucle indéfinie qui permet de répéter une séquence d’instructions tant qu’une condition est remplie.
  3. La structure de boucle définie qui permet de répéter une séquence d’instruction un nombre défini de fois.

Les deux premières structures de contrôle sont dites « conditionnelles », car elles utilisent une condition exprimée sous la forme d’une expression booléenne pour contrôler le chemin.

Objectifs

A la fin de ce travail, vous devez être capable de :

  1. reconnaître les différentes structures de contrôles et de comprendre leur fonctionnement;
  2. lire un algorithme décrit sous la forme d’un structogramme de Nassi-Schneidermann (GNS);
  3. créer un projet dans NetBeans sans aide;
  4. utiliser le débogueur (debugger) sans aide.

Ressources

Logiciel :

  • Oracle NetBeans

Mise en route

Séquence

La séquence est une structure que vous connaissez déjà. Pour réaliser une telle structure, il suffit d’écrire des instructions l’une à la suite de l’autre comme nous l’avons fait pour écrire l’algorithme d’Al-Khwârizmî. Le programme QuadraticEquation de la figure 1 montre une autre implémentation possible de cet algorithme.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package ch.epaifribourg.ict.m403;

import java.util.Scanner;

public class QuadraticEquation2 {

    public static void main(String [] args) {
        
        Scanner input = new Scanner(System.in);

        // Affiche un message d’information.
        System.out.println("Ce programme calcule la solution d’une équation de la forme x^2 + ax = b.\n");

        // Demande à l’utilisateur de saisir les valeurs de a et de b.
        System.out.print("Veuillez saisir la valeur de la variable a : ");
        double a = input.nextDouble();
        System.out.print("Veuillez saisir la valeur de la variable b : ");
        double b = input.nextDouble();
        
        // Calcule la valeur de a / 2 et stocke cette valeur dans une variable.
        double half = a / 2;

        // Calcule la solution de l’équation et l’affect à la variable result.
        double result = Math.sqrt(half * half + b) - half;

        // Affiche le résultat.
        System.out.printf("La solution est : %.1f\n", result);
    }
}
Fig. 1 – Code du programme QuadraticEquation2

Jusqu’ici, nous avons décrit nos algorithmes sous la forme d’un texte en français. Mais comme nous l’avons vu, les langues naturelles ont tendance à être ambiguës. Pour faciliter la lecture, nous avons présenté l’algorithme sous la forme d’une liste de manière à bien séparer les instructions. La liste fonctionne bien pour une séquence, mais n’est pas adaptée aux autres structures de contrôle. C’est pourquoi nous allons désormais présenter nos algorithmes sous la forme de diagramme appelé structogramme (diagramme de structure) ou graphe de Nassi-Schneidermann (GNS). Comme leur nom l’indique, ces diagrammes permettent de décrire la structure d’un programme de manière précise. Les instructions elles-mêmes sont toujours décrire en français.

La figure 2 montre comment on représente la séquence des instructions du programme QuadraticEquation à l’aide d’un structogramme (GNS).

Fig. 2 – Structogramme (GNS) du programme QuadraticEquation2
Fig. 2 – Structogramme (GNS) du programme QuadraticEquation2

Structure de choix si-alors-sinon (if-then-else)

La structure de choix également appelée « alternative » permet de choisir entre deux séquences d’instruction que la condition soit remplie ou non. La condition est exprimée à l’aide d’une expression booléenne dont la valeur peut être soit vrai (true) soit faux (false).

Pour expérimenter l’effet de cette structure, réalisez les programmes des figures 3, 4 et 5 à l’aide de NetBeans et exécutez-les avec le débogueur pour bien comprendre leur fonctionnement. Pour chaque programme, créez un nouveau projet dont le nom est celui du programme. Exécutez plusieurs fois chaque programme afin de pouvoir tester les différents chemins possibles du fil d’exécution.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package ch.epaifribourg.ict.m403;

import java.util.Scanner;

public class IsLessThan {

    public static void main(String[] args) {

        Scanner input = new Scanner(System.in);

        System.out.print("Veuillez saisir la valeur de a : ");
        int a = input.nextInt();

        if (a < 6) {

            System.out.println("la valeur de a est inférieure à 6.");

        } else {

            System.out.println("la valeur de a est supérieure ou égale à 6.");

        }

        System.out.print("Fin du programme.");
        
    }
}
Fig. 3 – Programme « IsLessThan »
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package ch.epaifribourg.ict.m403;

import java.util.Scanner;

public class IsEqualTo {

    public static void main(String[] args) {

        Scanner input = new Scanner(System.in);

        System.out.print("Veuillez saisir la valeur de a :");
        int a = input.nextInt();

        if (a == 6) {

            System.out.println("la valeur de a est égale à 6.");

        } else {

            System.out.println("la valeur de a n’est pas égale à 6.");

        }

        System.out.println("Fin du programme.");
      
    }
}
Fig. 4 – Programme « IsEqualTo »
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package ch.epaifribourg.ict.m403;

import java.util.Scanner;

public class IsInInterval {

    public static void main(String[] args) {

        Scanner input = new Scanner(System.in);

        System.out.print("Veuillez saisir une valeur entre 5 et 10 :");
        int a = input.nextInt();

        if (a >= 5 && a <= 10) {

            System.out.printf("La valeur %d est comprise entre 5 et 10\n", a);

        } else {

            System.out.printf("La valeur %d n’est pas comprise entre 5 et 10\n", a);

        }

        System.out.println("Fin du programme.");
      
    }
}
Fig. 5 – Programme « IsInInterval »

La figure 6 montre le structogramme du programme IsInInterval et illustre la manière de représenter une structure de choix dans ce formalisme.

Fig. 6 – Structogramme (GNS) du programme IsInInterval
Fig. 6 – Structogramme (GNS) du programme IsInInterval

Structure de boucle indéfinie (while)

La figure 7 montre le structogramme de l’algorithme d’Euclide qui permet de calculer le plus grand commun diviseur (PGCD) de deux nombres entiers a et b non nuls. Voici comment on pourrait décrire cet algorithme : 

  1. Demande les valeurs de a et b;
  2. répète 3, 4 et 5 tant que b > 0;
  3. calcule le reste de la division de a par b et stocke le résultat dans r;
  4. remplace a par b;
  5. remplace b par r;
  6. la valeur recherchée est a.

Même s’il est possible d’améliorer cette représentation, on constate qu’il n’est pas facile de repérer les instructions que l’on doit répéter. Le structogramme rend les choses plus claire comme le montre la figure 7.

Fig. 7 – Structogramme (GNS) du programme EuclideanAlgorithm
Fig. 7 – Structogramme (GNS) du programme EuclideanAlgorithm

Pour expérimenter l’effet de cette structure, réalisez le programme EuclideanAlgorithm avec NetBeans et exécutez-le à l’aide du débogueur.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package ch.epaifribourg.ict.m403;

import java.util.Scanner;

public class EuclideanAlgorithm {

    public static void main(String[] args) {

        Scanner input = new Scanner(System.in);
        
        System.out.println("Ce programme calcule le plus grand commun diviseur de deux nombres entiers non nuls.\n");
        
        System.out.print("Veuillez saisir le plus grand des deux nombres :");
        int a = input.nextInt();

        System.out.print("Veuillez saisir le plus petit des deux nombres :");
        int b = input.nextInt();

        while (b > 0) {
            int r = a % b;
            a = b;
            b = r;
        }
        
        System.out.printf("Le plus grand commun diviseur est : %d\n", a);
      
    }
}
Fig. 8 – Programme « EuclideanAlgorithm »

Structure de boucle définie (for)

Dans le programme précédent, on ne sait pas à l’avance le nombre de fois que les instructions de la boucle devront être répétées. En effet, la condition qui permet de sortir de la boucle dépend d’une valeur qui est calculée dans le corps de la boucle. On dit que la boucle est indéfinie. Lorsque le nombre de répétitions est connu avant d’entrer dans la boucle, on utilise une boucle définie. On appelle souvent cette structure « boucle for » car on décrit généralement une telle boucle en disant par exemple “pour chaque entier de min à max” ou, comme dans l’exemple de la figure 9, “pour chaque entier de 0 à n - 1”.

En Java, la syntaxe de la boucle définie est un peu plus compliquée que celle des autres structures de contrôle. En effet, la parenthèse ne contient pas uniquement une expression booléenne, mais trois parties distinctes séparées par des points virgule ;. Ces trois parties sont, dans l’ordre :

  1. La déclaration de la variable de boucle et l’affectation de la valeur initiale
    (p. ex. int i = 0).
  2. La condition : on continue tant qu’on a pas atteind la valeur finale
    (p. ex. i <= n - 1).
  3. L’incémentation de la variable de boucle
    (p. ex. i = i + 1 ou de manière plus brève i += 1).

Le nom de la variable de boucle est, par convention, généralement i. On peut également utiliser les noms j et k dans le cas où il est nécessaire d’imbriquer plusieurs boucles comme nous le verrons plus tard.

Réalisez programme de la figure 9 dans NetBeans et exécutez-le à l’aide du débogueur pour expérimenter l’effet de la structure de boucle définie.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package ch.epaifribourg.ict.m403;

import java.util.Scanner;

public class PrintNumbers {

    public static void main(String[] args) {

        Scanner input = new Scanner(System.in);
        
        System.out.println("Affiche les nombres de 0 à n-1.");
        System.out.println();
        
        System.out.print("Veuillez saisir la valeur de n : ");
        int n = input.nextInt();

        for (int i = 0; i <= n - 1; i += 1) {
            System.out.printf("%d ", i);
        }
                
        System.out.println();
        System.out.println("Fin du programme.");
    }
}
Fig. 9 – Programme PrintNumbers

La figure 10 montre le structogramme du programme PrintNumbers.

Fig. 7 – Structogramme (GNS) du programme PrintNumbers
Fig. 10 – Structogramme (GNS) du programme PrintNumbers

Tâches à effectuer

  1. Créez un projet par programme et exécutez chacun d’eux normalement et avec le débogueur pour analyser leur fonctionnement.
  2. Expliquez à quoi sert la fonction printf.
  3. Énumérez les différentes fonctions qui permettent d’afficher des messages dans la sortie standard.
  4. Quelle(s) instruction(s) devez-vous écrire pour lire une valeur depuis l’entrée standard ?
  5. Que signifie les caractères \n dans les chaînes de caractères de certains des programmes de cette activité ?
  6. Enumérez les opérateurs de comparaison de Java que vous avez utiliser durant cette activité. En existe-t-il d’autre ?
  7. Dans l’expression suivante Math.sqrt(half * half + b) - half (programme de la figure 1), enumérez les différentes opérations et indiquez l’ordre dans lequel elles sont effectuées.
  8. Modifier le programme PrintNumber pour afficher les nombres les uns sous les autres.