Les déclarations de boucles
Dans cette page, nous examinerons les constructions de programmation en boucle grâce auxquelles nous pouvons exécuter un extrait de code de manière répétée. Nous verrons comment implémenter des répétitions conditionnelles (boucles while et do-while) et comment travailler avec des boucles for. Nous donnerons des exemples de différentes possibilités pour définir des boucles, comment les construire et certaines de leurs utilisations clefs. Enfin, nous discuterons de la construction de boucle foreach et de la façon dont nous pouvons utiliser plusieurs boucles placées les unes dans les autres (boucles imbriquées).
Qu'est-ce qu'une « boucle » ?
En programmation, il faut souvent exécuter plusieurs fois une séquence d'opérations. Une boucle est une construction de programmation de base permettant l'exécution répétée d'un fragment de code source. Selon le type de boucle, le code qu'elle contient est répété un nombre fixe de fois ou se répète jusqu'à ce qu'une condition donnée soit vraie (existe).
Les boucles ne se terminant jamais sont appelées boucles infinies. L'utilisation d'une boucle infinie est rarement nécessaire, sauf dans les cas où, quelque part dans le corps de la boucle, un opérateur break est utilisé pour terminer son exécution prématurément. Nous aborderons cela plus tard, mais voyons maintenant comment créer une boucle en langage de programmation C#.
Les boucles while
L'une des boucles les plus simples et les plus couramment utilisées est while :
while (condition) { corps-de-la-boucle; } |
Dans l'exemple de code ci-dessus, la condition est une expression renvoyant un résultat booléen (vrai ou faux). Elle détermine la durée de répétition du corps de la boucle et est appelée condition de boucle. Dans cet exemple, le corps de la boucle est le code de programmation exécuté à chaque itération de la boucle, c'est-à-dire chaque fois que la condition d'entrée est vraie. Le comportement des boucles while peut être représenté par le schéma suivant :

Dans la boucle while, tout d'abord, l'expression booléenne est calculée et si elle est vraie, la séquence d'opérations dans le corps de la boucle est exécutée. Ensuite, la condition d'entrée est à nouveau vérifiée et si elle est à nouveau vraie, le corps de la boucle est exécuté. Tout cela est répété encore et encore jusqu'à ce qu'à un moment donné, l'expression conditionnelle renvoie la valeur false. À ce stade, la boucle s'arrête et le programme continue à la ligne suivante, immédiatement après le corps de la boucle.
Le corps de la boucle while peut ne pas être exécuté une seule fois si au début la condition du cycle renvoie false. Si la condition du cycle n'est jamais rompue, la boucle sera exécutée indéfiniment.
Utilisation des boucles while
Prenons un exemple très simple d'utilisation de la boucle while. Le but de la boucle est d'afficher sur la console les nombres compris entre 0 et 7 dans l'ordre croissant :
Lors de l'exécution de l'exemple de code, nous obtenons le résultat suivant :
Nombre : 0Nombre : 1
Nombre : 2
Nombre : 3
Nombre : 4
Nombre : 5
Nombre : 6
Nombre : 7
Donnons quelques exemples supplémentaires afin d'illustrer l'utilité des boucles et de montrer quelques problèmes pouvant être résolus en utilisant des boucles.
Somme des nombres de 1 à x
Dans cet exemple, nous allons examiner comment, en utilisant la boucle while, nous pouvons trouver la somme des nombres de 1 à x. Le nombre n est lu depuis la console :
Tout d'abord, nous initialisons les variables i et sum avec la valeur 1. Dans i, nous gardons le nombre courant, que nous ajoutons à la somme des nombres précédents. À chaque boucle, nous augmentons i de 1 pour obtenir le nombre suivant, puis dans la condition de la boucle, nous vérifions s'il est compris entre 1 et x. La variable sum contient la somme des nombres de 1 à i à tout moment. En entrant dans la boucle, nous ajoutons à sum le nombre suivant entreposé dans i. Nous affichons sur la console tous les nombres i de 1 à x avec un séparateur "+" et le résultat final de la sommation après la fin de la boucle. Le résultat de l'exécution du programme est le suivant (nous saisissons n = 16) :
N = 16The sum 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 = 136
Donnons un autre exemple d'utilisation de la boucle while, avant de passer à d'autres structures d'organisation des boucles.
Vérifier si un nombre est premier
Nous allons écrire un programme pour vérifier si un nombre donné est premier ou non. Nous allons lire le nombre à vérifier à partir de la console. Comme nous le savons grâce aux mathématiques, un nombre premier est tout nombre entier positif, n'étant divisible par aucun autre nombre sauf 1 et lui-même. Nous pouvons vérifier si le nombre i est premier lorsque, dans une boucle, nous vérifions s'il se divise par des nombres de 2 à √i :
Nous utilisons la variable diviseur pour entreposer la valeur d'un diviseur potentiel du nombre. Nous l'initialisons d'abord avec 2 (le plus petit diviseur possible). La variable maxDivider est le diviseur maximum possible, étant égal à la racine carrée du nombre. Si nous avons un diviseur plus grand que √i, alors i devrait aussi avoir un autre diviseur plus petit que √i et c'est pourquoi il est inutile de vérifier les nombres plus grands que √i. De cette façon, nous réduisons le nombre d'itérations de la boucle.
Pour le résultat, nous utilisons une variable booléenne appelée prime. Initialement, sa valeur est vraie. En parcourant la boucle, s'il s'avère que le nombre a un diviseur, la valeur de prime deviendra fausse.
La condition de la boucle while se compose de deux autres sous-conditions étant liées à l'opérateur logique (et logique). Afin d'exécuter la boucle, ces deux sous-conditions doivent être vraies simultanément. Si à un moment donné nous trouvons un diviseur du nombre i, la variable prime devient fausse et la condition de la boucle n'est plus satisfaite. Cela signifie que la boucle est exécutée jusqu'à ce qu'elle trouve le premier diviseur du nombre ou jusqu'à ce qu'elle prouve le fait que i n'est divisible par aucun des nombres compris entre 2 et √i.
Voici à quoi ressemble le résultat de l'exécution de l'exemple ci-dessus si les valeurs d'entrée sont respectivement les nombres 41 et 74 :
Entrez un nombre positif : 41Premier ? True
Entrez un nombre positif : 74
Premier ? False
L'opérateur "break"
L'opérateur break permet de quitter prématurément la boucle, avant qu'elle n'ait terminé son exécution de manière naturelle. Lorsque la boucle atteint l'opérateur break, elle est terminée et l'exécution du programme continue à partir de la ligne immédiatement après le corps de la boucle. La terminaison d'une boucle avec l'opérateur break ne peut être effectuée qu'à partir de son corps, lors d'une itération de la boucle. Lorsque break est exécuté, le code dans le corps de la boucle après celui-ci est ignoré et n'est pas exécuté. Nous allons démontrer la sortie d'une boucle avec break avec un exemple.
Calcul de la factorielle
Dans cet exemple, nous allons calculer la factorielle d'un nombre saisi à partir de la console. Le calcul est effectué à l'aide d'une boucle while infinie et de l'opérateur break. Rappelons-nous, en mathématiques, ce qu'est la factorielle et comment elle est calculée. La factorielle d'un entier n est une fonction qui est calculée comme un produit de tous les entiers inférieurs ou égaux à n ou égaux à lui. Elle s'écrit n! et par définition les formules suivantes sont valables pour elle :
- N! = 1 * 2 * 3 ... (n-1) * n, pour n> 1;
- 2! = 1 * 2;
- 1! = 1;
- 0! = 1.
Le produit n! peut être exprimé par un factoriel d'entiers inférieurs à n :
- N! = (N-1)! * N, en utilisant la valeur initiale de 0! = 1
Afin de calculer la factorielle de n nous utiliserons directement la définition :
Tout d'abord, nous initialisons la variable factorielle avec 1 et lisons n depuis la console. Nous construisons une boucle while sans fin en utilisant true comme condition de la boucle. Nous utilisons l'opérateur break, afin de terminer la boucle, lorsque n atteint une valeur inférieure ou égale à 1. Sinon, nous multiplions le résultat courant par n et nous réduisons n d'une unité. Pratiquement dans la première itération de la boucle, la variable factorielle a une valeur n, dans la deuxième - n*(n-1) et ainsi de suite. Dans la dernière itération de la boucle, la valeur de factorielle est le produit n*(n-1)*(n-2)*...*3*2, qui est la valeur souhaitée de n!.
Si nous exécutons le programme d'exemple et saisissons 7 en entrée, nous obtenons le résultat suivant :
7n! = 5040
Les boucles do-while
La boucle do-while est similaire à la boucle while, mais elle vérifie la condition après chaque exécution de son corps de boucle. Ce type de boucle est appelé boucle avec condition à la fin (boucle post-test). Une boucle do-while ressemble à ceci :
do { code-exécutable; } while (condition); |
De par leur conception, les boucles do-while sont exécutées selon le schéma suivant :

Au début, le corps de la boucle est exécuté. Ensuite, sa condition est vérifiée. Si elle est vraie, le corps de la boucle est répété, sinon la boucle se termine. Cette logique est répétée jusqu'à ce que la condition de la boucle soit rompue. Le corps de la boucle est exécuté au moins une fois. Si la condition de la boucle est constamment vraie, la boucle ne se termine jamais.
Utilisation des boucles do-while
La boucle do-while est utilisée lorsque nous voulons garantir que la séquence d'opérations qu'elle contient sera exécutée de manière répétée et au moins une fois au début de la boucle.
Calcul de la factorielle
Dans cet exemple, nous allons à nouveau calculer la factorielle d'un nombre donné n, mais cette fois, au lieu d'une boucle while infinie, nous utiliserons une boucle do-while. La logique est similaire à celle de l'exemple précédent :
Au début, nous commençons avec un résultat de 1 et multiplions consécutivement le résultat à chaque itération par n, et réduisons n d'une unité, jusqu'à ce que n atteigne 0. Cela nous donne le produit n*(n-1)*...*1. Enfin, nous imprimons le résultat sur la console. Cet algorithme effectue toujours au moins une multiplication et c'est pourquoi il ne fonctionnera pas correctement lorsque n ≤ 0.
Voici le résultat de l'exécution de l'exemple ci-dessus pour n=10 :
n = 10n! = 3628800
Factorielle d'un grand nombre
Vous vous demandez peut-être ce qui se passerait si nous définissions une valeur élevée pour le nombre n dans l'exemple précédent, disons n=100. Ensuite, lors du calcul du n!, nous dépasserions le type décimal et le résultat serait une exception de type System.OverflowException :
n = 100 Unhandled Exception: System.OverflowException: Value was either too large or too small for a Decimal. at System.Decimal.FCallMultiply(Decimal& result, Decimal d1, Decimal d2) at System.Decimal.op_Multiply(Decimal d1, Decimal d2) at Factorial.Program.Main() in C:\Projects\Factorial\Program.cs:line 5 |
Si nous voulons calculer 100 ! nous pouvons utiliser le type de données BigInteger (étant nouveau à partir de .NET Framework 4.0 et dans .NET Core et manquant dans les anciennes versions de .NET). Ce type représente un entier, pouvant être très grand (par exemple 100 000 chiffres). Il n'y a pas de limite à la taille des nombres enregistrés dans la classe BigInteger (tant que vous avez suffisamment de mémoire vive).
Pour utiliser BigInteger, nous devons d'abord ajouter une référence de notre projet à l'assembly System.Numerics.dll (il s'agit d'une bibliothèque .NET standard pour travailler avec des entiers très grands, n'étant pas référencée par défaut par nos projets Visual Studio). L'ajout d'une référence à celui-ci se fait en cliquant avec le bouton droit sur les références du projet actuel dans la fenêtre Explorateur de solutions de Visual Studio :

Nous recherchons et choisissons l'assembly System.Numerics.dll dans la liste :

Il faut ensuite ajouter "using System.Numerics;" avant le début de la classe de notre programme et remplacer decimal par BigInteger. Le programme prendra la forme suivante :
Si nous exécutons maintenant le programme pour n=120, nous obtiendrons la valeur factorielle 120, étant un nombre à 198 chiffres :
n = 120n! = 6689502913449127057588118054090372586752746333138029810295671352301633557244962989366874165271984981308157637893214090552534408589408121859898481114389650005964960521256960000000000000000000000000000
Avec BigInteger, vous pouvez calculer 1000!, 10000! et même 100000! Cela prendra un certain temps, mais aucune exception OverflowException ne se produira. La classe BigInteger est très puissante mais elle fonctionne beaucoup plus lentement que int et long.
Produit dans l'intervalle [N...M]
Donnons un autre exemple plus intéressant de travail avec des boucles do-while. L'objectif est de trouver le produit de tous les nombres dans l'intervalle [n...m]. Voici un exemple de solution à ce problème :
Dans l'exemple de code, nous attribuons consécutivement à num à chaque itération les valeurs n, n+1,..., m et dans la variable product nous accumulons le produit de ces valeurs. Nous demandons à l'utilisateur de saisir n, devant être inférieur à m. Sinon, nous recevrons comme résultat le nombre n.
Si nous exécutons le programme pour n=3 et m=7, nous obtiendrons le résultat suivant :
n = 3m = 7
produit[n...m] = 2520
Attention : le produit grandit très vite, vous devrez donc peut-être utiliser BigInteger au lieu de long pour le résultat calculé. Méfiez-vous également du dépassement d'entier caché. Le code non vérifié débordera silencieusement et le code ci-dessus produira une sortie incorrecte au lieu d'afficher une erreur. Pour surmonter ce problème, vous pouvez entourer la ligne contenant la multiplication par le mot-clef checked.
Les boucles for
Les boucles for sont légèrement plus compliquées que les boucles while et do-while, mais d'un autre côté, elles peuvent résoudre des tâches plus complexes avec moins de code. Voici le schéma décrivant les boucles for :

Elles contiennent un bloc d'initialisation (A), une condition (B), un corps (D) et des commandes de mise à jour pour les variables de boucle (C). Nous les expliquerons en détail sous peu. Avant cela, regardons à quoi ressemble le code de programme d'une boucle for :
for (initialisation; condition; opération) { corps de la boucle; } |
Elle se compose d'une partie d'initialisation pour le compteur (dans le modèle int i = 0), d'une condition booléenne (i < 10), d'une expression pour la mise à jour du compteur (i++, cela peut être i-- ou par exemple, i = i + 4) et du corps de la boucle.
Le compteur de la boucle la distingue des autres types de boucles. Le plus souvent, le compteur passe d'une valeur initiale donnée à une valeur finale dans l'ordre croissant, par exemple de 1 à 100. Le nombre d'itérations d'une boucle for donnée est généralement connu avant le début de son exécution. Une boucle for peut avoir une ou plusieurs variables de boucle se déplaçant dans l'ordre croissant ou décroissant ou par pas. Il est possible qu'une variable de boucle augmente et l'autre diminue. Il est même possible de faire une boucle de 2 à 1024 par pas de multiplication par 2, puisque la mise à jour des variables de boucle peut contenir non seulement une addition, mais aussi toute autre opération arithmétique (ainsi que d'autres).
Étant donné qu'aucun des éléments répertoriés des boucles for n'est obligatoire, nous pouvons tous les ignorer et nous obtiendrons une boucle infinie :
for ( ; ; ) corps de la boucle; } |
Considérons maintenant en détail les différentes parties d'une boucle for.
Initialisation des boucles for
Les boucles for peuvent avoir un bloc d'initialisation :
Elle n'est exécutée qu'une seule fois, juste avant d'entrer dans la boucle. En général, le bloc d'initialisation est utilisé pour déclarer la variable compteur (également appelée variable de boucle) et pour définir sa valeur initiale. Cette variable est "visible" et ne peut être utilisée qu'à l'intérieur de la boucle. Dans le bloc d'initialisation, il est possible de déclarer et d'initialiser plusieurs variables.
Condition de la boucle for
Les boucles For peuvent avoir une condition de boucle :
La condition (condition de boucle) est évaluée une fois avant chaque itération de la boucle, comme dans les boucles while. Pour un résultat true, le corps de la boucle est exécuté, pour un résultat false, il est ignoré et la boucle se termine (le programme continue immédiatement après la dernière ligne du corps de la boucle).
Mise à jour des variables de boucle
Le dernier élément d'une boucle for contient du code mettant à jour la variable de boucle :
Ce code est exécuté à chaque itération, après l'exécution du corps de la boucle. Il est le plus souvent utilisé pour mettre à jour la valeur de la variable compteur.
Le corps de la boucle
Le corps de la boucle contient un bloc avec le code source. Les variables de boucle, déclarées dans le bloc d'initialisation de la boucle, y sont disponibles.
Voici un exemple complet de boucle for :
Le résultat de son exécution est le suivant :
0 1 2 3 4 5 6 7 8 9 10Voici un autre exemple, plus compliqué, de boucle for, dans lequel nous avons deux variables i et sum, ayant initialement la valeur 1, mais nous les mettons à jour consécutivement à chaque itération de la boucle :
Le résultat de l'exécution de cette boucle est le suivant :
i=1, sum=1i=2, sum=3
i=4, sum=7
i=8, sum=15
i=16, sum=31
i=32, sum=63
i=64, sum=127
i=128, sum=255
Calcul de N^M
En guise d'exemple supplémentaire, nous allons écrire un programme élevant le nombre n à une puissance de m, et pour cela nous utiliserons une boucle for :
Tout d'abord, nous initialisons le résultat (result = 1). La boucle commence par définir une valeur initiale pour la variable compteur (int i = 0). Nous définissons la condition d'exécution de la boucle (i < m). De cette façon, la boucle sera exécutée de 0 à m-1, c'est-à-dire exactement m fois. À chaque exécution de la boucle, nous multiplions le résultat par n et ainsi n sera élevé à la puissance supérieure (1, 2, ..., m) à chaque itération. Enfin, nous imprimons le résultat pour voir si le programme fonctionne correctement.
Voici à quoi ressemble le résultat du programme pour n = 2 et m = 10 :
n = 2m = 8
n^m = 256
Boucle for avec plusieurs variables
Comme nous l'avons déjà vu, dans la construction d'une boucle for, nous pouvons utiliser plusieurs variables en même temps. Voici un exemple dans lequel nous avons deux compteurs. L'un des compteurs monte de 1 et l'autre descend de 10 :
La condition pour terminer la boucle est le chevauchement des compteurs. Finalement, nous obtenons le résultat suivant :
1 102 9
3 8
4 7
5 6
L'opérateur "continue"
L'opérateur continue arrête l'itération en cours de la boucle interne, sans terminer la boucle. Avec l'exemple suivant, nous allons voir comment utiliser cet opérateur.
Nous allons calculer la somme de tous les entiers impairs dans la plage [1...n], n'étant pas divisibles par 7 en utilisant la boucle for :
Nous initialisons d'abord la variable de la boucle avec une valeur de 1 car il s'agit du premier entier impair dans l'intervalle [1...n]. Après chaque itération de la boucle, nous vérifions si i n'a pas encore dépassé n (i <= n). Dans l'expression de mise à jour de la variable, nous l'augmentons de 2 afin de ne passer que par les nombres impairs. À l'intérieur du corps de la boucle, nous vérifions si le nombre actuel est divisible par 7. Si c'est le cas, nous appelons l'opérateur continue, ignorant le reste du corps de la boucle (il ignore l'ajout du nombre actuel à la somme). Si le nombre n'est pas divisible par sept, elle continue avec la mise à jour de la somme avec le nombre actuel.
Le résultat de l'exemple pour n = 12 est le suivant :
12sum = 29
Les boucles foreach
La boucle foreach (boucle for étendue) est nouvelle pour la famille de langages de programmation C/C++/C#, mais elle est bien connue des programmeurs VB et PHP. Cette construction de programmation permet d'itérer sur tous les éléments d'un tableau, d'une liste ou d'une autre collection d'éléments (IEnumerable). Elle passe par tous les éléments de la collection spécifiée même si la collection n'est pas indexée.
Nous pouvons imaginer un tableau comme une séquence ordonnée de nombres ou d'autres éléments. Voici à quoi ressemble une boucle foreach :
foreach (type variable in collection) { instructions; } |
Comme nous le voyons, elle est nettement plus simple que la boucle for standard et est donc très souvent préférée par les développeurs car elle permet d'économiser l'écriture lorsque vous devez parcourir tous les éléments d'une collection donnée. Voici un exemple montrant comment nous pouvons utiliser foreach :
Dans l'exemple, nous créons un tableau de nombres, qui sont ensuite parcourus avec une boucle foreach, et ses éléments sont affichés sur la console. Ensuite, un tableau de noms de villes (chaînes de caractères) est créé et de la même manière, il est parcouru et ses éléments sont affichés sur la console. Le résultat de l'exemple est :
1 2 3 5 7 11 13 17 19 21Sept-Iles Alma Laval Montréal
Les boucles imbriquées
Les boucles imbriquées sont des constructions de programmation composées de plusieurs boucles situées les unes dans les autres. La boucle la plus interne est exécutée plus de fois, et la plus externe moins de fois. Voyons à quoi ressemblent deux boucles imbriquées :
for (initialisation, vérification, opération) { for (initialisation, vérification, opération) { code-exécutable } ... } |
Après l'initialisation de la première boucle for, l'exécution de son corps va commencer, contenant la deuxième boucle (imbriquée). Sa variable va être initialisée, sa condition va être vérifiée et le code dans son corps va être exécuté, puis la variable va être mise à jour et l'exécution va continuer jusqu'à ce que la condition renvoie false. Après cela, la deuxième itération de la première boucle for va continuer, sa variable va être mise à jour et toute la deuxième boucle va être exécutée une fois de plus. La boucle interne va être entièrement exécutée autant de fois que le corps de la boucle externe.
Considérons maintenant un exemple réel qui va démontrer à quel point les boucles imbriquées sont utiles.
Afficher un triangle de nombres continues
Résolvons le problème suivant : pour un nombre n donné, afficher sur la console un triangle avec n lignes, ressemblant à ceci :
11 2
1 2 3
...
1 2 3 ... n
Nous allons résoudre le problème avec deux boucles for. La boucle externe parcourra les lignes et la boucle interne les éléments qu'elles contiennent. Lorsque nous sommes sur la première ligne, nous devons afficher "1" (1 élément, 1 itération de la boucle interne). Sur la deuxième ligne, nous devons afficher "1 2" (2 éléments, 2 itérations de la boucle interne). Nous voyons qu'il existe une corrélation entre la ligne sur laquelle nous sommes et le nombre d'éléments que nous affichons. Cela nous indique comment organiser la structure de la boucle interne :
- On initialise la variable de boucle à 1 (le premier nombre que l'on va afficher) : col = 1;
- La condition de répétition dépend de la ligne sur laquelle on se trouve : col <= ligne;
- On augmente la variable de boucle d'une unité à chaque itération de la boucle interne.
En gros, nous devons implémenter une boucle for (externe) de 1 à n (pour les lignes) et y placer une autre boucle for (interne) - pour les nombres de la ligne courante, devant tourner de 1 au numéro de la ligne courante. La boucle externe doit parcourir les lignes tandis que la boucle interne - parcourt les colonnes de la ligne courante.
Finalement, nous obtenons le code suivant :
Si nous l'exécutons, nous nous assurerons qu'il fonctionne correctement. Voici à quoi ressemble le résultat pour n=12 :
11 2
1 2 3
1 2 3 4
1 2 3 4 5
1 2 3 4 5 6
1 2 3 4 5 6 7
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10 11
1 2 3 4 5 6 7 8 8 10 11 12
Afficher un triangle Pascal
Un triangle de Pascal (ou triangle arithmétique) est un arrangement triangulaire des coefficients binomiaux. Il a été nommé en l'honneur de Blaise Pascal, bien qu'il ait été étudié bien avant lui dans diverses cultures.
Le triangle est construit de la manière suivante :
- Le sommet du triangle (première ligne) contient un seul 1.
- Chaque ligne commence et se termine par 1.
- Chaque élément interne est la somme des deux éléments situés juste au-dessus dans la ligne précédente.
Voici un programme en C# qui génère un triangle de Pascal en fonction du nombre de lignes spécifié :
- using System;
-
- class Program
- {
- static void Main()
- {
- Console.Write("Entrez le nombre de lignes du triangle de Pascal : ");
- int n = int.Parse(Console.ReadLine());
-
- int[][] triangle = GeneratePascalTriangle(n);
-
- Console.WriteLine("\nTriangle de Pascal :");
- PrintPascalTriangle(triangle);
- }
-
- static int[][] GeneratePascalTriangle(int n)
- {
- int[][] triangle = new int[n][];
-
- for (int i = 0; i < n; i++)
- {
- triangle[i] = new int[i + 1];
- triangle[i][0] = 1; // Premier élément de chaque ligne
- triangle[i][i] = 1; // Dernier élément de chaque ligne
-
- for (int j = 1; j < i; j++)
- {
- triangle[i][j] = triangle[i - 1][j - 1] + triangle[i - 1][j];
- }
- }
-
- return triangle;
- }
-
- static void PrintPascalTriangle(int[][] triangle)
- {
- int n = triangle.Length;
-
- for (int i = 0; i < n; i++)
- {
- // Ajout d'espaces pour centrer le triangle
- Console.Write(new string(' ', (n - i - 1) * 2));
-
- for (int j = 0; j <= i; j++)
- {
- Console.Write($"{triangle[i][j],4}");
- }
- Console.WriteLine();
- }
- }
- }
Si nous l'exécutons, nous nous assurerons qu'il fonctionne correctement. Voici à quoi ressemble le résultat pour une entrée avec le nombre 12 :
Entrez le nombre de lignes du triangle de Pascal : 12Triangle de Pascal :
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1
1 10 45 120 210 252 210 120 45 10 1
1 11 55 165 330 462 462 330 165 55 11 1
Nombres premiers dans un intervalle
Considérons un autre exemple de boucles imbriquées. Nous nous fixons comme objectif d'afficher sur la console tous les nombres premiers dans l'intervalle [n...m]. Nous allons limiter l'intervalle par une boucle for et afin de vérifier un nombre premier, nous utiliserons une boucle while imbriquée :
- Console.Write("n = ");
- int n = int.Parse(Console.ReadLine());
- Console.Write("m = ");
- int m = int.Parse(Console.ReadLine());
- for (int num = n; num <= m; num++) {
- bool prime = true;
- int divider = 2;
- int maxDivider = (int)Math.Sqrt(num);
- while (divider <= maxDivider) {
- if (num % divider == 0) {
- prime = false;
- break;
- }
- divider++;
- }
- if (prime) {
- Console.Write(" " + num);
- }
- }
En utilisant la boucle for externe, nous vérifions si chacun des nombres n, n+1,..., m est premier. À chaque itération de la boucle for externe, nous vérifions si sa variable de boucle num est un nombre premier. La logique par laquelle nous vérifions un nombre premier nous est déjà familière. Au début, nous initialisons la variable prime avec true. Avec la boucle while interne, nous vérifions pour chacun des nombres [2...√num] s'il s'agit d'un diviseur de num et si c'est le cas, nous définissons prime sur false. Après avoir terminé la boucle while, la variable booléenne prime indique si le nombre est premier ou non. Si le nombre est premier, nous l'affichons sur la console. Si nous exécutons l'exemple pour n=3 et m=77, nous obtiendrons le résultat suivant :
n = 3m = 77
3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73
Numéros chanceux
Prenons un autre exemple grâce auquel nous montrerons que nous pouvons mettre plus de deux boucles l'une dans l'autre. Notre objectif est de trouver et d'afficher tous les nombres à quatre chiffres de type ABCD, où : A+B = C+D (nous les appelons numéros chanceux). Nous allons l'implémenter avec quatre boucles for - une pour chaque chiffre. La boucle la plus externe définira les milliers. Elle commencera à 1 et les autres boucles - à 0. Elles détermineront les centaines, les dizaines et les unités. Nous allons vérifier si notre nombre actuel dans la boucle la plus interne est un nombre porte-bonheur et si c'est le cas, nous l'imprimerons sur la console. Voici un exemple d'implémentation :
Voici une partie du résultat affiché (le résultat entier est trop long) :
1 0 0 11 0 1 0
1 1 0 2
1 1 1 1
1 1 2 0
1 2 0 3
1 2 1 2
1 2 2 1
1 2 3 0
1 3 0 4
1 3 1 3
1 3 2 2
1 3 3 1
1 3 4 0
1 4 0 5
1 4 1 4
1 4 2 3
1 4 3 2
1 4 4 1
1 4 5 0
1 5 0 6
1 5 1 5
1 5 2 4
1 5 3 3
1 5 4 2
...
Loterie 6/49
Dans l'exemple suivant, nous allons trouver toutes les combinaisons possibles du jeu de loterie «6/49». Nous devons trouver et afficher tous les extraits possibles de 6 nombres différents, chacun étant dans l'intervalle [1...49]. Nous utiliserons 6 boucles for. Contrairement à l'exemple précédent, les nombres ne peuvent pas être répétés. Pour éviter les répétitions, nous nous efforcerons de faire en sorte que chaque nombre suivant soit plus grand que le précédent. Par conséquent, les boucles internes ne commenceront pas à partir de 1 mais à partir du nombre auquel la boucle précédente est arrivée + 1. Nous devrons parcourir la première boucle jusqu'à ce qu'elle atteigne 44 (et non 49), la deuxième - 45,... La dernière boucle ira jusqu'à 49. Si vous faites toutes les boucles jusqu'à 49, vous recevrez des nombres correspondants dans certaines combinaisons. Pour la même raison, chaque cycle suivant démarre à partir du compteur de boucle précédent + 1. Voyons ce qui va se passer :
- for (int i1 = 1; i1 <= 44; i1++) {
- for (int i2 = i1 + 1; i2 <= 45; i2++) {
- for (int i3 = i2 + 1; i3 <= 46; i3++) {
- for (int i4 = i3 + 1; i4 <= 47; i4++) {
- for (int i5 = i4 + 1; i5 <= 48; i5++) {
- for (int i6 = i5 + 1; i6 <= 49; i6++) {
- Console.WriteLine(i1 + " " + i2 + " " + i3 + " " + i4 + " " + i5 + " " + i6);
- }
- }
- }
- }
- }
- }
Tout semble correct. Exécutons le programme, il affichera 13 983 816 lignes pour chacune des combinaisons possibles. Il semble fonctionner mais il y a un problème : il y a trop de combinaisons et le programme ne se termine pas (il est si lent que presque personne n'attend).