Section courante

A propos

Section administrative du site

 Langage  Installation  Elément  Tutoriel  Programmation  Bibliothèque  Cadre d'application  SDK  Gabarit  Projet  IDE  Outils  Annexe  Aide 
ABAP/4
Ada
Assembleur
Assembly & bytecode
ASP (Active Server Pages)
Basic
C
C++
C# (C Sharp)
Cobol
ColdFusion
Fortran
HTML
Java
JavaScript
LISP
Logo
LotusScript
Oberon
Pascal
Perl
PHP
PL/1
Prolog
Python
Rebol
REXX
Ruby
Rust
SAS
NoSQL
SQL
Swift
X++ (Axapta)
GNAT
SMALLAda
VHDL
Assembleur 370
Assembleur 1802
Assembleur 4004
Assembleur 6502
Assembleur 6800
Assembleur 68000
Assembleur 8080 et 8085
Assembleur 8089
Assembleur 80x86
Assembleur AGC4
Assembleur ARM
Assembleur DPS 8000
Assembleur i860
Assembleur Itanium
Assembleur MIPS
Assembleur PDP-11
Assembleur PowerPC
Assembleur RISC-V
Assembleur SPARC
Assembleur SuperH
Assembleur UNIVAC I
Assembleur VAX
Assembleur Z80
Assembleur Z8000
Assembleur z/Architecture
ASSEMBLER/MONITOR 64
Micol Assembler
GFA Assembler
A86
MASM (Macro Assembler)
TASM (Turbo Assembler)
CIL
Jasmin
LLVM
MSIL
Parrot
P-Code (PCode)
SWEET16
G-Pascal
ASP 1.0
ASP 2.0
ASP 3.0
ASP.NET
ASP.NET Core
ABasiC (Amiga)
Adam SmartBASIC
Altair BASIC
AmigaBASIC (Amiga)
AMOS Basic (Amiga)
Atari Basic (Atari 400, 600 XL, 800, 800XL)
Basic Apple II (Integer BASIC/APPLESOFT)
Basic Commodore 64 (CBM-BASIC)
Basic Commodore 128 (BASIC 7.0)
Basic Commodore VIC-20 (CBM-BASIC 2.0)
Basic Coco 1 (Color Basic)
Basic Coco 2 (Extended Color Basic)
Basic Coco 3 (Extended Color Basic 2.0)
BASICA (PC DOS)
Basic Pro
BBC BASIC
Blitz BASIC (Amiga)
DarkBASIC
Dartmouth BASIC
GFA-Basic (Atari ST/Amiga)
GWBASIC (MS-DOS)
Liberty BASIC
Locomotive BASIC (Amstrad CPC)
MSX-Basic
Omikron Basic (Atari ST)
Oric Extended Basic
Power Basic
Quick Basic/QBasic (MS-DOS)
Sinclair BASIC (ZX80, ZX81, ZX Spectrum)
ST BASIC (Atari ST)
Turbo Basic
Vintage BASIC
VBScript
Visual Basic (VB)
Visual Basic .NET (VB .NET)
Visual Basic pour DOS
Yabasic
BeckerBASIC
SIMONS' BASIC
Basic09 d'OS-9
Disk Extended Color Basic
Basic09 d'OS-9
Disk Extended Color Basic
Access
Excel
Visual Basic pour Windows
Visual Basic .NET pour Windows
C Shell Unix (csh)
C pour Amiga
C pour Atari ST
C pour DOS
C pour Falcon030
C pour GEMDOS (Atari ST)
C pour Linux
C pour PowerTV OS
C pour OS/2
C pour Unix
C pour Windows
Aztec C
CoCo-C
GNU C
HiSoft C
IBM C/2
Introl-C
Lattice C
Microsoft C
MinGW C
MSX-C
Open Watcom C
OS-9 C Compiler
Pure C
Quick C
Turbo C
HiSoft C for Atari ST
HiSoft C for CP/M (Amstrad CPC)
C++ pour OS/2
C++ pour Windows
Borland C++
C++Builder
IBM VisualAge C++
Intel C++
MinGW C++
Open Watcom C++
Symantec C++
Turbo C++
Visual C++
Visual C++ .NET
Watcom C++
Zortech C++
C# (C Sharp) pour Windows
Apple III Cobol
Microsoft Cobol
BlueDragon
Lucee
OpenBD
Railo
Smith Project
Microsoft Fortran
WATFOR-77
CSS
FBML
Open Graph
SVG
XML
XSL/XSLT
LESS
SASS
GCJ (GNU)
JSP
Jython
Visual J++
Node.js
TypeScript
AutoLISP
ACSLogo
LotusScript pour Windows
Amiga Oberon
Oberon .NET
Apple Pascal
Delphi/Kylix/Lazarus
Free Pascal
GNU Pascal
HighSpeed Pascal
IBM Personal Computer Pascal
Lisa Pascal
Maxon Pascal
MPW Pascal
OS-9 Pascal
OSS Personal Pascal
Pascal-86
Pascal du Cray Research
Pascal/VS
Pascal-XT
PURE Pascal
QuickPascal
RemObjets Chrome
Sun Pascal
THINK Pascal
Tiny Pascal (TRS-80)
Turbo Pascal
UCSD Pascal
VAX Pascal
Virtual Pascal
Turbo Pascal for CP/M-80
Turbo Pascal for DOS
Turbo Pascal for Macintosh
Turbo Pascal for Windows
CodeIgniter (Cadre d'application)
Drupal (Projet)
Joomla! (Projet)
Phalanger (PHP .NET)
phpBB (Projet)
Smarty (balise)
Twig (balise)
Symfony (Cadre d'application)
WordPress (Projet)
Zend (Cadre d'application)
PL360
PL/M-80
PL/M-86
Turbo Prolog
CPython
IronPython
Jython
PyPy
AREXX
Regina REXX
JMP
Btrieve
Cassandra
Clipper
CouchDB
dBASE
Hbase
Hypertable
MongoDB
Redis
Access
BigQuery
DB2
H2
Interbase
MySQL
Oracle
PostgreSQL
SAP HANA
SQL Server
Sybase
U-SQL
Visual C# 2005 Express
Visual Studio .NET 2003
Visual Studio 2005
Visual Studio 2008
Visual Studio 2010
Visual Studio 2012
Visual Studio 2013
Visual Studio 2015
Visual Studio 2017
Visual Studio 2019
Introduction
Les remarques
Les opérateurs
Les instructions conditionnelles
Les instructions de boucles
Les instructions d'exceptions
Type de données élémentaires
Définition de variables
Définitions de tableaux
Requêtes de données (LINQ)
Référence des mots réservés
Référence des espaces de nom (Namespace)
Les classes
Références des classes
Directives de préprocesseur C#
Les nombres
Les chaines de caractères
Date et heure
Vue par catégorie
Les interfaces
Les classes abstraites
Les classes scellés
Les indexeurs
Les premiers pas
Les fondements de C#
Les types primitifs et variables
Les opérateurs et les expressions
Les entrées/sorties de la console
Les déclarations conditionnelles
Les déclarations de boucles
Les systèmes numériques
Traitement des chaînes de caractères et du texte
WinForms (Windows Forms)
Les opérations
Conversion de string à int
Bonjour
Astronomie
Base de données
Biochimie
Chaine de caractères
Electricité
Finance
Géographie
Géométrie
Gouvernement
Histoire
Mathématique
Médicale
Météorologie
Océanographie
Sport
Système d'exploitation
Temps
Tri
Trigonométrie
Validation
Phase lunaire
Table SQL Server
Calcul du calcium corrigé
Calcul le taux d'alcoolémie
Nombre réel avec un certain nombre de décimal
Majuscule (strtoupper ou UpperCase)
Minuscule (strtolower ou LowerCase)
Calcul du tarif d'une piscine pour 1 mois
IPaymt/Interet
NPer
PPaymt/Principal
Distance en Km entre deux longitudes et latitudes
Aire d'un cercle
Aire d'une surface de prisme rectangulaire
Aire d'un triangle
Distance entre deux points
Taxe de vente canadienne
Chiffre romain
Ackermann
Exp
Factoriel
Fibonacci
Log
Nombre premier
Odd
Random
Sqrt
Triangle Pascal
Valeur absolue (ABS)
Hauteur utérine
Unité de mesure
Fréquence des vagues
Hockey
Variables d'environnement
Année bissextile
Date de la Pâque
Heure courante
FirstDayOfMonth
Tri à bulle (Bubble Sort)
Tri Shell Sort
ArcCos
ArcSin
Atn/ATan/ArcTan/ArcTangente
Cos
Sin
Courriel
ALGLIB
Dapper
ElmahCore
FluentFTP
log4net
MailKit
MediatR
MimeKit
Newtonsoft.Json (Json.NET)
Serilog
.NET
.NET Core
.NET Framework
Accord.NET Framework
Akka.NET
ASP.NET
ASP.NET Core
Avalonia UI
Blazor
Entity Framework
Entity Framework Core (EF Core)
Hangfire
Infer.NET
MAUI
ML.NET
Mono
NHibernate
NUnit
Unity
xUnit.net
Azure SDK for .NET
AWS SDK for .NET
Bot Framework SDK
Razor
Umbraco
Rider
Visual Studio
Visual Studio Code
Visual C# 2005 Express
Xamarin Studio
Visual Studio .NET
Visual Studio .NET 2003
Visual Studio 2005
Visual Studio 2008
Visual Studio 2010
Visual Studio 2012
Visual Studio 2013
Visual Studio 2015
Visual Studio 2017
Visual Studio 2019
Visual Studio 2022
ELMAH
elmah.io
MS Build Tools
NuGet
WiX Toolset
Add-in Express
csc (C# Compiler)
CFF Explorer
IL DASM
ILMerge
.NET Reflector
Salamander .NET Decompiler
Références des codes d'erreur du C# (C Sharp)
Base de connaissances
Conventions de nommage
Vocabulaire
Marqueurs
Archives de paquet externe
Bibliographie
Préface
Notes légal
Dictionnaire
Recherche

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 :

  1. // Initialiser le compteur
  2. int i = 0;
  3. // Exécuter le corps de la boucle pendant que la condition de la boucle est respectée
  4. while (i <= 7) {
  5.  // Afficher la valeur du compteur
  6.  Console.WriteLine("Nombre : " + i);
  7.  // Incrémenter le compteur
  8.  i++;
  9. }

Lors de l'exécution de l'exemple de code, nous obtenons le résultat suivant :

Nombre : 0
Nombre : 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 :

  1. Console.Write("x = ");
  2. int x = int.Parse(Console.ReadLine());
  3. int i = 1;
  4. int sum = 1;
  5. Console.Write("La somme de 1");
  6. while (i < x) {
  7.  i++;
  8.  sum += i;
  9.  Console.Write(" + " + i);
  10. }
  11. Console.WriteLine(" = " + sum);

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 = 16
The 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 :

  1. Console.Write("Entrez un nombre positif :");
  2. int i = int.Parse(Console.ReadLine());
  3. int divider = 2;
  4. int maxDivider = (int)Math.Sqrt(i);
  5. bool prime = true;
  6. while (prime && (divider <= maxDivider)) {
  7.  if (i % divider == 0) {
  8.   prime = false;
  9.  }
  10.  divider++;
  11. }
  12. Console.WriteLine("Premier ? " + prime);

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 : 41
Premier ? 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 :

Le produit n! peut être exprimé par un factoriel d'entiers inférieurs à n :

Afin de calculer la factorielle de n nous utiliserons directement la définition :

  1. int n = int.Parse(Console.ReadLine());
  2. // « décimal » est le plus grand type C# pouvant contenir des valeurs entières
  3. decimal factorial = 1;
  4. // Effectuer une « boucle infinie »
  5. while (true) {
  6.  if (n <= 1) {
  7.   break;
  8.  }
  9.  factorial *= n;
  10.  n--;
  11. }
  12. Console.WriteLine("n! = " + factorial);     

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 :

7
n! = 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 :

  1. Console.Write("n = ");
  2. int n = int.Parse(Console.ReadLine());
  3. decimal factorial = 1;
  4. do {
  5.  factorial *= n;
  6.  n--;
  7. } while (n > 0);
  8. Console.WriteLine("n! = " + factorial);

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 = 10
n! = 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 :

  1. using System;
  2. using System.Numerics;
  3. class Factorial {
  4.  static void Main() {
  5.   Console.Write("n = ");
  6.   int n = int.Parse(Console.ReadLine());
  7.   BigInteger factorial = 1;
  8.   do {
  9.    factorial *= n;
  10.    n--;
  11.   } while (n > 0);
  12.   Console.WriteLine("n! = " + factorial);
  13.  }
  14. }

Si nous exécutons maintenant le programme pour n=120, nous obtiendrons la valeur factorielle 120, étant un nombre à 198 chiffres :

n = 120
n! = 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 :

  1. Console.Write("n = ");
  2. int n = int.Parse(Console.ReadLine());
  3. Console.Write("m = ");
  4. int m = int.Parse(Console.ReadLine());
  5. int num = n;
  6. long product = 1;
  7. do {
  8.  product *= num;
  9.  num++;
  10. } while (num <= m);
  11. Console.WriteLine("produit[n...m] = " + product);

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 = 3
m = 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 :

  1. for (int i = 0; ...; ...) {
  2.  // La variable i est visible ici et elle peut être utilisée
  3. }
  4. // Ici, i ne peut pas être utilisé

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 :

  1. for (int i = 0; i < 10; ...) {
  2.  // Corps de la boucle
  3. }

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 :

  1. for (int i = 0; i < 10; i++) {
  2.  // Corps de la boucle
  3. }

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 :

  1. for (int i = 0; i <= 10; i++) {
  2.  Console.Write(i + " ");
  3. }

Le résultat de son exécution est le suivant :

0 1 2 3 4 5 6 7 8 9 10

Voici 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 :

  1. for (int i = 1, sum = 1; i <= 128; i = i * 2, sum += i) {
  2.  Console.WriteLine("i={0}, sum={1}", i, sum);
  3. }

Le résultat de l'exécution de cette boucle est le suivant :

i=1, sum=1
i=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 :

  1. Console.Write("n = ");
  2. int n = int.Parse(Console.ReadLine());
  3. Console.Write("m = ");
  4. int m = int.Parse(Console.ReadLine());
  5. decimal result = 1;
  6. for (int i = 0; i < m; i++) {
  7.  result *= n;
  8. }
  9. Console.WriteLine("n^m = " + result);

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 = 2
m = 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 :

  1. for (int i=1, j=10; i<j; i++, j--) {
  2.  Console.WriteLine(i + " " + j);
  3. }

La condition pour terminer la boucle est le chevauchement des compteurs. Finalement, nous obtenons le résultat suivant :

1 10
2 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 :

  1. int n = int.Parse(Console.ReadLine());
  2. int sum = 0;
  3. for (int i = 1; i <= n; i += 2) {
  4.  if (i % 7 == 0) {
  5.   continue;
  6.  }
  7.  sum += i;
  8. }
  9. Console.WriteLine("Somme = " + sum);

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 :

12
sum = 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 :

  1. int[] nombres = { 1, 2, 3, 5, 7, 11, 13, 17, 19, 21 };
  2. foreach (int i in nombres) {
  3.  Console.Write(" " + i);
  4. }
  5. Console.WriteLine();
  6. string[] villes = { "Sept-Iles", "Alma", "Laval", "Montréal" };
  7. foreach (string ville in villes) {
  8.  Console.Write(" " + ville);
  9. }

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 21
 Sept-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 :

1
1 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 :

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 :

  1. int n = int.Parse(Console.ReadLine());
  2. for (int ligne = 1; ligne <= n; ligne++) {
  3.  for (int col = 1; col <= ligne; col++) {
  4.   Console.Write(col + " ");
  5.  }
  6.  Console.WriteLine();
  7. }

Si nous l'exécutons, nous nous assurerons qu'il fonctionne correctement. Voici à quoi ressemble le résultat pour n=12 :

1
1 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 :

Voici un programme en C# qui génère un triangle de Pascal en fonction du nombre de lignes spécifié :

  1. using System;
  2.  
  3. class Program
  4. {
  5.     static void Main()
  6.     {
  7.         Console.Write("Entrez le nombre de lignes du triangle de Pascal : ");
  8.         int n = int.Parse(Console.ReadLine());
  9.  
  10.         int[][] triangle = GeneratePascalTriangle(n);
  11.  
  12.         Console.WriteLine("\nTriangle de Pascal :");
  13.         PrintPascalTriangle(triangle);
  14.     }
  15.  
  16.     static int[][] GeneratePascalTriangle(int n)
  17.     {
  18.         int[][] triangle = new int[n][];
  19.  
  20.         for (int i = 0; i < n; i++)
  21.         {
  22.             triangle[i] = new int[i + 1];
  23.             triangle[i][0] = 1; // Premier élément de chaque ligne
  24.             triangle[i][i] = 1; // Dernier élément de chaque ligne
  25.  
  26.             for (int j = 1; j < i; j++)
  27.             {
  28.                 triangle[i][j] = triangle[i - 1][j - 1] + triangle[i - 1][j];
  29.             }
  30.         }
  31.  
  32.         return triangle;
  33.     }
  34.  
  35.     static void PrintPascalTriangle(int[][] triangle)
  36.     {
  37.         int n = triangle.Length;
  38.  
  39.         for (int i = 0; i < n; i++)
  40.         {
  41.             // Ajout d'espaces pour centrer le triangle
  42.             Console.Write(new string(' ', (n - i - 1) * 2));
  43.  
  44.             for (int j = 0; j <= i; j++)
  45.             {
  46.                 Console.Write($"{triangle[i][j],4}");
  47.             }
  48.             Console.WriteLine();
  49.         }
  50.     }
  51. }

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 : 12

Triangle 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 :

  1. Console.Write("n = ");
  2. int n = int.Parse(Console.ReadLine());
  3. Console.Write("m = ");
  4. int m = int.Parse(Console.ReadLine());
  5. for (int num = n; num <= m; num++) {
  6.  bool prime = true;
  7.  int divider = 2;
  8.  int maxDivider = (int)Math.Sqrt(num);
  9.  while (divider <= maxDivider) {
  10.   if (num % divider == 0) {
  11.    prime = false;
  12.    break;
  13.   }
  14.   divider++;
  15.  }
  16.  if (prime) {
  17.   Console.Write(" " + num);
  18.  }
  19. }

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 = 3
m = 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 :

  1. for (int a = 1; a <= 9; a++) {
  2.  for (int b = 0; b <= 9; b++) {
  3.   for (int c = 0; c <= 9; c++) {
  4.    for (int d = 0; d <= 9; d++) {
  5.     if ((a + b) == (c + d)) {
  6.      Console.WriteLine(" " + a + " " + b + " " + c + " " + d);
  7.     }
  8.    }
  9.   }
  10.  }
  11. }

Voici une partie du résultat affiché (le résultat entier est trop long) :

1 0 0 1
1 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 :

  1. for (int i1 = 1; i1 <= 44; i1++) {     
  2.  for (int i2 = i1 + 1; i2 <= 45; i2++) {
  3.   for (int i3 = i2 + 1; i3 <= 46; i3++) {
  4.    for (int i4 = i3 + 1; i4 <= 47; i4++) {
  5.     for (int i5 = i4 + 1; i5 <= 48; i5++) {
  6.      for (int i6 = i5 + 1; i6 <= 49; i6++) {
  7.       Console.WriteLine(i1 + " " + i2 + " " + i3 + " " + i4 + " " + i5 + " " + i6);
  8.      }
  9.     }
  10.    }
  11.   }
  12.  }
  13. }

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).



PARTAGER CETTE PAGE SUR
Dernière mise à jour : Samedi, le 21 décembre 2024