Vous êtes sur la page 1sur 266

Programmez avec le Langage C++

Par Dr.Ibrahim Benabdallah


Sommaire

1.Introduction à la Programmation en C++


1.Découvrir le C++
2.Outils Essentiels pour Programmer
3.Votre Premier Programme en C++
4.Gestion de la Mémoire
5.Contrôle de Flux
6.Modularisation du Code avec des Fonctions
7.Travailler avec des Tableaux
8.Lecture et Écriture de Fichiers
9.TP : Le Défi du Mot Mystère
10.Maîtriser les Pointeurs
2. Programmation Orientée Objet (POO)
1.Fondements des Classes (Partie 1/2)
2.Fondements des Classes (Partie 2/2)
3.Surcharge d'Opérateurs
4.TP : POO en Action avec ZFraction
5.Classes et Utilisation de Pointeurs
6.Comprendre l'Héritage
7.Le Polymorphisme
8.Éléments Statiques et Amitié
3. Création d'Interfaces Utilisateur avec Qt
1.Introduction à Qt
2.Création de votre Première Fenêtre Qt
3.Personnalisation des Widgets
4.Signaux et Slots
5.Boîtes de Dialogue Courantes
6.Naviguer dans la Documentation de Qt
7.Agencement des Widgets avec des Layouts
8.Présentation des Principaux Widgets
9.TP : ZeroClassGenerator
10.Conception de Fenêtres avec Qt Designer
11.TP : zNavigo - Votre Navigateur Web Personnel
Sommaire

4.Utilisation de la Bibliothèque Standard


1.Manipulation des Conteneurs
2.Exploration des Itérateurs et des Foncteurs
3.Exploiter la Puissance des Algorithmes
4.Approfondir la STL (Standard Template Library)
5.Notions Avancées en C++
1.Gestion des Erreurs avec les Exceptions
2.Création et Utilisation de Templates
3.Opportunités d'Apprentissage Continu
Programmez avec le langage C++
Difficulté : Difficile
Durée d'étude : 3 mois minimum

Si la programmation en C++ vous intéresse mais que sa


complexité apparente vous intimide, ne vous alarmez pas ! Ce
cours de C++ a été spécialement élaboré pour les débutants qui
n'ont aucune expérience en programmation.

Le langage de programmation C++ jouit d'une reconnaissance


mondiale en tant que l'un des plus célèbres. Il est particulièrement
apprécié dans l'industrie du jeu vidéo en raison de ses
performances exceptionnelles et de ses fonctionnalités étendues,
ce qui en fait un incontournable pour les développeurs.
Programmez avec le langage C++
Difficulté : Difficile
Durée d'étude : 3 mois minimum

Le C++ a évolué à partir du langage C, bien que présentant des


similitudes apparentes, ils diffèrent en réalité de manière
significative. Le C++ introduit de nouvelles fonctionnalités,
notamment la programmation orientée objet (POO), ce qui en fait
un langage puissant offrant une approche distincte de la
programmation par rapport au C.
Pendant ce cours, nous examinerons également une
bibliothèque appelée Qt. Cette bibliothèque étend
considérablement les capacités du C++ en nous permettant de
concevoir des interfaces graphiques, des menus, et même
d'accéder aux fonctionnalités réseau de votre ordinateur.
Partie 1 : [Théorie] Découverte de C++
Qu'est-ce que le C++ ?
Si vous êtes passionné par l'informatique et que vous souhaitez apprendre
à programmer, pourquoi ne pas vous lancer ? La programmation peut
sembler complexe au début, mais elle est en réalité plus accessible que
vous ne le pensez.
Les programmes

Les programmes sont la fondation de l'informatique, permettant l'exécution


d'opérations sur l'ordinateur. Pour illustrer cela, considérons la capture
d'écran ci-dessous, montrant trois fenêtres correspondant à trois
programmes distincts, classés de l'avant-plan à l'arrière-plan :
Partie 1 : [Théorie] Découverte de C++

Comme vous pouvez le remarquer, chacun de ces programmes est


conçu avec un objectif spécifique en tête. Par exemple, les jeux tels
que Starcraft II (visible dans la figure suivante), World of Warcraft,
Worms, Team Fortress 2, et bien d'autres encore, sont créés pour offrir
du plaisir. Chacun de ces titres représente un programme distinct
Parmi les exemples courants, on trouve le navigateur web Google
Chrome, qui permet de consulter des sites web ; l'explorateur de
fichiers, qui facilite la gestion des fichiers sur votre ordinateur ; ainsi que
le traitement de texte Microsoft Word, qui sert à rédiger des lettres et
des documents.

Tous les programmes ne sont pas nécessairement visibles, comme c'est le cas de ceux qui surveillent les mises à
jour disponibles. Cela vaut également pour votre ordinateur et, dans une moindre mesure, pour votre logiciel
antivirus. Tous ces éléments fonctionnent en arrière-plan, sans nécessairement afficher une fenêtre, mais cela ne
les empêche pas d'être actifs et de travailler en coulisses !
"Si vous souhaitez également créer vos propres programmes, voici les étapes à suivre :"?
"Pour commencer, il est essentiel de définir clairement vos ambitions. Par exemple, la création
d'un jeu comme Starcraft II nécessite l'implication de dizaines de développeurs à plein temps
pendant plusieurs années. Il est donc important de ne pas se fixer des objectifs excessivement
difficiles à atteindre.

Maintenant, en ce qui concerne la création de programmes : la programmation est un domaine


vaste qui repose sur l'utilisation de langages de programmation pour indiquer à l'ordinateur ce
que nous voulons qu'il accomplisse. Penchons-nous de manière plus détaillée sur ces langages
de programmation.

Les langages de programmation sont essentiels pour interagir avec votre ordinateur, une
machine aussi étonnante que complexe. À sa base, l'ordinateur ne comprend qu'un langage très
simplifié, composé de 0 et de 1. Ainsi, un message tel que celui-ci :
1010010010100011010101001010111010100011010010... peut signifier quelque chose comme
"Affiche une fenêtre à l'écran"."
C’est vraiment difficile ? Devrons-nous vraiment nous plonger dans
l'apprentissage de ce langage ?
Heureusement non.

Si l'on devait écrire en langage binaire, comme le langage binaire, la création d'un jeu tel que
Starcraft II prendrait non pas des années, mais des millénaires (et ce n'est pas une exagération
!). Donc, pour commencer, il est important d'avoir des ambitions bien définies.

Par exemple, pour créer un jeu comme Starcraft II, il faut l'implication de dizaines de
développeurs à plein temps pendant plusieurs années. Par conséquent, il est essentiel de ne
pas se fixer des objectifs excessivement difficiles à atteindre.

Cependant, si vous décidez de suivre ce cours, vous acquerrez des bases solides en
développement de programmes. Au cours des travaux pratiques, nous irons même jusqu'à
créer notre propre navigateur web simplifié, à la manière de Mozilla Firefox ou Google Chrome !
Vous serez en mesure de concevoir des programmes avec des interfaces graphiques. Si vous
le souhaitez, avec un effort supplémentaire, vous pourrez même créer des jeux en 2D et 3D. En
fin de compte, avec le temps et une persévérance continue, vous pourrez accomplir des
réalisations remarquables.
Bien sûr, je n'oublie pas votre question : comment créer des programmes ?

La programmation est un domaine vaste qui repose sur l'utilisation de langages de


programmation pour communiquer à l'ordinateur ce que nous souhaitons qu'il réalise. Pour
mieux comprendre ces langages de programmation, explorons-les plus en détail.

Les langages de programmation sont essentiels pour interagir avec votre ordinateur, une
machine aussi fascinante que complexe. À sa base, l'ordinateur ne comprend qu'un langage
extrêmement simplifié, composé uniquement de 0 et de 1. Ainsi, un message tel que celui-ci :
1010010010100011010101001010111010100011010010... peut signifier quelque chose comme
"Affiche une fenêtre à l'écran".

ça semble vraiment complexe ! Devons-nous vraiment maîtriser le langage binaire ?


Heureusement non.

Si nous devions utiliser le langage binaire, également connu sous le nom de langage binaire,
pour créer un jeu comme Starcraft II, cela ne prendrait pas des années, mais littéralement des
millénaires (et je ne plaisante pas !).
Pour faciliter les choses, les informaticiens ont développé des langages intermédiaires, bien plus
simples que le binaire. À ce jour, il existe des centaines de langages de programmation. Pour
avoir une idée plus précise, vous pouvez consulter une liste de langages de programmation sur
Wikipédia. Chacun de ces langages a ses propres caractéristiques, que nous explorerons plus en
détail.

1.Vous rédigez des instructions pour l'ordinateur dans un langage de programmation, tel que le
C++.
2.Ces instructions sont traduites en langage binaire grâce à un programme de « traduction ».
3.L'ordinateur peut ensuite lire le langage binaire et exécuter les actions que vous avez
demandées. Résumons ces étapes dans un schéma, comme illustré dans la figure suivante.

La compilation
Le fameux "programme de traduction" est en réalité appelé un compilateur. Il s'agit d'un outil essentiel
qui vous permet de convertir votre code, écrit dans un langage de programmation, en un véritable
programme exécutable.
Revoyons le schéma précédent en utilisant un langage informatique approprié, comme le montre
la figure suivante.

La compilation en détail

e que je vous encourage à retenir pour le moment, c'est que ce n'est pas excessivement
compliqué, mais c'est une base essentielle à maîtriser absolument !

Je vous incite à retenir que, pour le moment, cela n'est pas excessivement complexe, mais
constitue une base essentielle à acquérir absolument !

Effectivement, choisir le langage de programmation peut paraître complexe étant donné la variété
d'options disponibles, dont certaines sont plus appropriées pour certaines tâches que d'autres. Le
choix dépendra de plusieurs facteurs, notamment vos objectifs, votre niveau de compétence, le
type de projet que vous envisagez, les ressources disponibles et vos préférences personnelles
Il est nécessaire de commencer par l'un d'entre eux, et la bonne nouvelle, c'est que vous pouvez
choisir celui qui vous convient le mieux ! Les principes fondamentaux des langages de
programmation sont souvent similaires, ce qui facilite la transition entre eux. Cependant,
explorons ce qui distingue le C++ des autres langages, car c'est le sujet de ce cours. Quelles sont
ses spécificités et avantages par rapport aux autres langages ?

• Le C++ face aux autres langages?


• Le C++ : langage de haut ou de bas niveau ?

Parmi les centaines de langages de programmation disponibles, certains sont


incontestablement plus populaires que d'autres. Le C++ est clairement l'un de ces langages très
populaires. Des sites comme langpop.com tiennent un classement des langages les plus
couramment utilisés, si cette information vous intéresse. Vous constaterez que le C, le Java et le
C++ sont fréquemment en tête de ce classement.

La question qui se pose est la suivante : doit-on choisir un langage simplement parce qu'il est
populaire ? En réalité, il existe des langages moins courants mais très intéressants. Le problème
avec les langages moins répandus réside dans la difficulté à trouver de l'aide et des conseils en
cas de besoin. C'est l'une des raisons pour lesquelles le choix du C++ est recommandé pour les
débutants : il dispose d'une communauté de développeurs suffisamment vaste pour offrir de
l'assistance en cas de besoin !
Bien sûr, la popularité n'est pas le seul critère à prendre en compte. À mon avis, le critère le plus
crucial est le niveau du langage. Il existe des langages de haut niveau et d'autres de niveau plus
bas.

Qu'es t-ce u'un langage de haut niveau ?

le C++ est un langage relativement éloigné du langage binaire (et donc du fonctionnement de la
machine), ce qui vous offre généralement une flexibilité et une rapidité accrues dans le
développement.

En revanche, un langage de bas niveau se rapproche davantage du fonctionnement interne de la


machine. Il demande généralement un peu plus d'efforts, mais il vous confère également un plus
grand contrôle sur vos opérations. C'est un compromis à double tranchant.

Le schéma ci-après illustre quelques langages de programmation classés par


"niveau" (voir la figure suivante).
Il est possible de programmer en langage binaire en utilisant
un langage très basique appelé l'assembleur. Cependant, en
raison de la complexité qu'il implique, même pour des tâches
simples telles que la création d'une calculatrice, la plupart des
développeurs préfèrent utiliser un langage de programmation
plus accessible.
En programmation, la notion de "niveau" est relative. De
manière générale, le C++ est considéré comme "bas niveau"
par rapport au Python, mais il est considéré comme "haut
niveau" par rapport à l'assembleur. Tout dépend du contexte
et de la perspective adoptée.

Le C++ appartient à la deuxième catégorie, celle des langages "de


bas niveau". Cependant, ne soyez pas intimidé ! Bien que la
programmation en C++ puisse sembler complexe, vous aurez
accès à un langage extrêmement puissant et particulièrement
rapide. En effet, la grande majorité des jeux vidéo sont développés
en C++ en raison de sa capacité à combiner efficacité et vitesse.
C'est pourquoi il est considéré comme un langage incontournable
dans ce domaine.
Résumé des forces du C++
• Il jouit d'une large diffusion et figure parmi les langages de programmation les plus utilisés à
l'échelle mondiale, offrant ainsi une abondance de ressources documentaires en ligne et une
communauté de soutien active sur les forums. Il est particulièrement rapide, ce qui en fait un choix
privilégié pour les applications nécessitant des performances élevées, telles que les jeux vidéo, les
outils financiers et les logiciels militaires en temps réel.

• Sa portabilité est un atout majeur, permettant aux mêmes codes sources d'être convertis en
exécutables pour Windows, Mac OS et Linux sans nécessiter de réécriture. Le C++ propose
également une vaste gamme de bibliothèques, étendant ses fonctionnalités pour le développement
d'applications 3D, réseau, audio, interfaces graphiques, et plus encore.

• Sa polyvalence permet d'adopter différentes approches de programmation, dont la Programmation


Orientée Objet (POO), qui simplifie l'organisation du code et la réutilisation. La partie II de ce cours
sera entièrement consacrée à la POO !
Résumé des forces du C++

Le C++ n'est pas le seul choix. Il présente quelques inconvénients par rapport à d'autres langages, notamment
sa complexité. Le C++ offre un haut niveau de contrôle sur le fonctionnement de l'ordinateur, y compris la
gestion de la mémoire, ce qui confère une grande puissance. Cependant, une utilisation incorrecte peut
entraîner des plantages du programme. Rassurez-vous, nous aborderons ces aspects progressivement dans
ce cours.

Code : C++
Petit aperçu du C++
À titre d'exemple, voici un programme extrêmement Using namespace
simple qui affiche le message « Hello World! » à l'écran.
Traditionnellement, « Hello World » est le tout premier
programme que l'on crée en programmation. Ce sera l'un
std; int main()
des premiers morceaux de code que nous examinerons
dans les prochains chapitres. {
cout << "Hello world!" << endl;
return 0;
La petite histoire du C++
}
La programmation a une longue histoire. À ses débuts, il n'y avait même
pas de clavier pour programmer ! On utilisait des cartes perforées,
similaires à celles-ci, pour donner des instructions à l'ordinateur, comme
illustré dans la figure suivante.
Autant dire que cette méthode était longue et fastidieuse !
De l'Algol au C++
Heureusement, les choses ont évolué par la suite avec
l'introduction des claviers et des premiers langages de
programmation :

• En 1958, à une époque où les ordinateurs étaient énormes et


pesaient autant qu'une maison, l'Algol est apparu en tant que
premier langage de programmation majeur. Dans les années
1960-1970, alors que la technologie progressait, le langage
CPL a évolué en BCPL puis en langage B. En 1970, une étape
significative a été franchie avec la création du langage C, qui
reste l'un des langages les plus utilisés de nos jours, comme
indiqué précédemment sur www.codeur.com.
• En 1983, quelques années plus tard, une proposition d'extension du langage C a été faite, conduisant
à l'émergence du langage « C++ ». C++ est en fait basé entièrement sur le langage C, mais il
introduit de nouveaux concepts de programmation avancés tels que la programmation orientée objet,
le polymorphisme, les flux, etc. Nous aurons l'occasion d'examiner ces notions plus en détail plus tard
!
Attendez une minute... Si le C++ est essentiellement une extension du C, pourquoi tant de
personnes continuent-elles à programmer en C ?

Le concepteur de C++

C'est Bjarne Stroustrup, un informaticien d'origine danoise, qui a conçu le langage C++.
Insatisfait des capacités du langage C, il l'a étendu en 1983 pour créer le C++, ajoutant les
fonctionnalités qu'il jugeait manquantes. Malgré son âge, le langage C++ continue d'évoluer,
avec une nouvelle version en préparation appelée « C++1x ». Il ne s'agit pas d'un nouveau
langage, mais d'une mise à jour du C++, avec des fonctionnalités complexes que nous
n'aborderons pas ici !
Bjarne Stroustrup est actuellement professeur d'informatique à l'université Texas A&M aux États-
Unis. Il est une figure importante de l'informatique, dont le nom mérite d'être connu, du moins si
vous parvenez à vous en souvenir ! Le C++ a également eu une influence significative sur de
nombreux autres langages de programmation, dont le Java.

Tout le monde n'a pas besoin des améliorations apportées par le langage C++. Le langage C offre
des fonctionnalités suffisantes pour servir de base aux systèmes d'exploitation tels que Linux,
Mac OS X et Windows. Pour ceux qui n'ont pas besoin des améliorations (et de la complexité) du
C++, le langage C reste adapté, malgré sa longue histoire. Cela montre que l'âge d'un langage
n'entrave pas sa pertinence continue.

En résumé
• Les programmes informatiques permettent une variété d'actions sur un ordinateur, comme la
navigation sur le Web, la rédaction de textes, la manipulation de fichiers, etc. Pour créer des
programmes, on rédige des instructions dans un langage de programmation, appelé code source,
qui doit être traduit en langage binaire par un compilateur pour être exécuté. Le C++ est un
langage de programmation répandu et rapide, évoluant à partir du langage C et offrant la
programmation orientée objet, un concept puissant abordé dans ce cours.
Les logiciels nécessaires pour programmer
Maintenant que nous avons acquis quelques connaissances sur le C++, pourquoi ne pas passer
à la pratique pour plonger directement dans le vif du sujet ? Avant de commencer à programmer,
il est essentiel d'installer les bons logiciels spécifiques pour le C++. Dans le prochain chapitre,
nous les mettrons en place et les découvrirons ensemble. Patience, car dès le chapitre suivant,
nous pourrons enfin nous lancer dans la programmation proprement dite !

Les outils nécessaires au programmeur


Maintenant, quels outils un programmeur doit-il avoir à sa disposition ? Si vous avez suivi
attentivement, vous devriez déjà en reconnaître au moins un !
Vous suivez ce dont je parle, n'est-ce pas ?

Exactement, vous avez raison ! Il s'agit bien du compilateur, cet outil essentiel qui traduit votre
code C++ en langage machine compréhensible par l'ordinateur. Il existe plusieurs compilateurs
pour le langage C++, mais nous verrons que le choix du compilateur ne sera pas très compliqué
dans notre situation.

Eh bien, je ne vais pas prolonger le suspense davantage. Voici le strict minimum dont un
programmeur a besoin :
Un éditeur de texte est nécessaire pour rédiger le code source en C++. En principe, des logiciels
comme le Bloc-Notes sous Windows ou Vi sous Linux peuvent convenir. Cependant, l'idéal est
d'utiliser un éditeur de texte intelligent qui applique automatiquement une coloration syntaxique
au code, facilitant ainsi la navigation et la compréhension. C'est pourquoi aucun développeur
averti ne se contente du Bloc-Notes. De plus, un compilateur est requis pour traduire le code
source en code binaire exécutable, et un débogueur est indispensable pour identifier et corriger
les erreurs dans le programme. Malheureusement, il n'existe pas encore de "correcteur"
automatique capable de résoudre toutes nos erreurs de programmation.

À première vue, vous pourriez peut-être vous passer d'un débogueur si vous êtes un cas
extrêmement rare. Cependant, je suis convaincu qu'environ cinq minutes plus tard, vous
reviendrez me demander où trouver un débogueur fiable.
Dorénavant, nous avons deux options :
Une méthode plus complexe consiste à récupérer ces trois programmes séparément, ce qui
fonctionne mais peut être compliqué. En particulier, de nombreux programmeurs sous Linux
préfèrent utiliser ces trois programmes individuellement. Cependant, je vais vous présenter la
méthode simple : utiliser un programme "3-en-1" (comme les liquides vaisselle) qui combine un
éditeur de texte, un compilateur et un débogueur. Ces programmes "3-en-1" sont appelés IDE
(ou EDI en français, pour "Environnement de Développement Intégré").
Il existe plusieurs environnements de développement parmi lesquels choisir, et il peut être difficile
de décider lequel vous préférez au début. Cependant, il est important de noter que vous pouvez
créer n'importe quel type de programme avec n'importe quel IDE que vous choisissez.
Les projets
Lorsque vous créez un programme, vous travaillez sur un projet, qui peut inclure divers fichiers
de code source tels que .cpp, .h, ainsi que des éléments tels que des images. L'IDE a pour
fonction de regrouper tous ces fichiers d'un projet au sein d'une même interface, vous permettant
d'accéder à tous les éléments de votre programme en un simple clic. C'est pourquoi, lorsque vous
souhaitez créer un nouveau programme, vous devez demander à l'IDE de créer un « nouveau
projet ».
Choisissez votre IDE

Il est pertinent de mentionner quelques-uns des IDE les plus populaires, qui sont tous disponibles
gratuitement.

L'un de mes IDE préférés est Code::Blocks, disponible gratuitement sur la plupart des systèmes
d'exploitation, y compris Windows, Mac et Linux. Je vous recommande de commencer avec
celui-ci. Une autre option populaire sous Windows est Visual C++, qui a une version gratuite
appelée Visual C++ Express, offrant des performances similaires à la version payante.
Cependant, Visual C++ est exclusif à Windows.
Sous Mac OS X, vous avez également la possibilité d'utiliser XCode, qui est généralement
inclus sur le CD d'installation du système d'exploitation. C'est un IDE largement apprécié par
les développeurs Mac, mais il est exclusif à Mac OS X.

À tous les utilisateurs de Linux : bien que de nombreux IDE soient disponibles sous
Linux, certains programmeurs expérimentés préfèrent parfois compiler
manuellement, une méthode légèrement plus complexe. Vous en apprendrez
davantage sur cette approche plus tard. Pour le moment, nous commencerons par
utiliser un IDE. Si vous êtes sous Linux, je vous recommande d'installer Code::Blocks
pour suivre mes explications. Vous pouvez également explorer Eclipse for C/C++, un
environnement très puissant qui, contrairement à ce que l'on pense généralement, ne
se limite pas à la programmation en Java.

Quel est le meilleur de tous ces IDE ?

Tous ces IDE vous permettront de programmer et de suivre le reste de ce cours sans problème.
Certains sont plus complets en termes d'options, tandis que d'autres sont plus intuitifs à utiliser.
Cependant, quelle que soit l'IDE que vous choisissez, les programmes que vous créerez seront les
mêmes. Pour la durée de ce cours, j'utiliserai Code::Blocks. Si vous souhaitez avoir exactement les
mêmes écrans que moi, en particulier au début pour éviter toute confusion, je vous recommande
donc d'installer Code::Blocks.
Code::Blocks (Windows, Mac OS, Linux)
Code::Blocks est un IDE libre et gratuit, disponible pour Windows, Mac et Linux. Bien qu'il soit actuellement
disponible uniquement en anglais, cela ne devrait PAS vous décourager de l'utiliser. Nous n'utiliserons que
rarement les menus. Cependant, il est important de noter que lorsque vous programmerez, vous serez
fréquemment confronté à des documentations en anglais. C'est donc une raison de plus pour vous exercer à
utiliser cette langue.

Télécharger Code::Blocks
Visitez la page de téléchargement de Code::Blocks.

Si vous utilisez Windows, dirigez-vous vers la section "Windows" située un peu plus bas sur
cette page. Téléchargez le logiciel en optant pour le programme contenant "mingw" dans son
nom (par exemple : codeblocks-20.03mingw-32bit-setup.exe). L'autre version ne comprend
pas de compilateur, ce qui vous causerait des problèmes lors de la compilation de vos
programmes.

Si vous utilisez Linux, la meilleure méthode est de l'installer via les dépôts (par exemple, en
utilisant la commande "apt-get" sous Ubuntu). Vous devrez également installer le compilateur
séparément, en utilisant le paquet "build-essential". Pour installer à la fois le compilateur et
l'IDE Code::Blocks, vous pouvez utiliser la commande suivante :
Et pour les utilisateurs de Mac, il vous suffit de sélectionner le fichier le plus récent dans la
liste des téléchargements disponibles.
apt-get install build-essential codeblocks

Je tiens à confirmer l'importance de choisir la version du programme d'installation qui


inclut "mingw" si vous utilisez Windows. Sélectionner la mauvaise version pourrait
entraîner des problèmes lors de la compilation de vos programmes ultérieurement.
Assurez-vous de télécharger la version correcte pour un fonctionnement sans souci.

Code Blocks avec mingw


L'installation est très simple et rapide. Laissez toutes les options par défaut et lancez le programme.

3
2

Code Blocks
La fenêtre de Code::Blocks se compose de quatre principales sections, comme indiqué dans la figure suivante :

1. La barre d'outils : Cette section contient divers boutons et options, mais nous utiliserons principalement
quelques-uns d'entre eux.
2. La liste des fichiers du projet : À gauche, vous verrez la liste de tous les fichiers source de votre programme.
Si vous n'avez pas encore créé de projet, cette section sera vide, mais elle se remplira à mesure que vous
avancerez dans le cours.
3. La zone principale : C'est l'endroit où vous rédigerez votre code en langage C++.
4. La zone de notification : Aussi connue sous le nom de "Zone de la mort," c'est l'endroit où s'afficheront les
erreurs de compilation si votre code contient des erreurs, ce qui peut arriver assez souvent.

Dans la barre d'outils, une section particulièrement importante contient les boutons suivants dans cet
ordre : Compiler, Exécuter, Compiler & Exécuter, et Tout recompiler, comme illustré dans la figure
suivante. Ces boutons seront fréquemment utilisés, alors assurez-vous de les mémoriser.

Icônes de compilation
Pour clarifier les actions de ces boutons :

Compiler : Cette action envoie tous les fichiers source de votre projet au compilateur, qui génère un
exécutable. Si des erreurs sont détectées pendant la compilation, l'exécutable ne sera pas créé, et les
erreurs seront affichées en bas de Code::Blocks.
•Exécuter : Ce bouton lance simplement le dernier exécutable que vous avez compilé. Il vous permet de
tester votre programme pour voir son fonctionnement. Généralement, vous compilez d'abord, puis
exécutez le binaire résultant pour le tester.

•Compiler & Exécuter : Cette option effectue les deux étapes en une seule. Elle compile le code source
et exécute immédiatement le programme, vous montrant les résultats ou les erreurs en un seul clic.
C'est un moyen pratique de vérifier rapidement votre code.

•Les boutons Compiler et Exécuter vous permettent donc de contrôler les étapes de compilation et
d'exécution de votre programme.
•.

Utiliser des raccourcis clavier est effectivement une excellente pratique pour gagner du
temps et travailler de manière plus efficace. Voici quelques raccourcis clavier utiles dans
Code::Blocks :
F9 : Compiler & Exécuter (très pratique pour tester rapidement votre code).;F11 : Lancer
le débogueur (nous verrons le débogage plus tard dans le cours).
Ctrl + F9 : Compiler seulement.
Ctrl + F10 : Exécuter le programme sans le recompiler (si vous avez déjà compilé
auparavant).
N'hésitez pas à les utiliser pour accélérer votre flux de travail lorsque vous programmez
en C++ avec Code::Blocks.
Créer un nouveau projet

La création d'un nouveau projet est en effet une étape importante pour commencer à
programmer en C++ avec Code::Blocks. Une fois que vous avez suivi ces étapes et
sélectionné "Console application," vous pourrez configurer les paramètres de votre projet,
tels que le nom, l'emplacement des fichiers, et d'autres options spécifiques à votre projet.
Cela vous permettra de commencer à écrire et à exécuter votre code C++ dans
l'environnement de développement intégré de Code::Blocks.

Pour créer un nouveau projet, c'est très simple : suivez ces étapes :
• Allez dans le menu "File" (Fichier).
• Sélectionnez "New" (Nouveau).
• Choisissez "Project" (Projet).
Dans la fenêtre qui s'ouvre, choisissez "Console application" (Application console), comme
illustré dans la figure suivante.
Nouveau projet
Code::Blocks offre la possibilité de créer divers types de programmes, incluant ceux utilisant
des bibliothèques populaires comme SDL (pour la 2D), OpenGL (pour la 3D), Qt et
wxWidgets (pour les interfaces graphiques), entre autres. Cependant, à ce stade, ces
options sont principalement décoratives, car ces bibliothèques ne sont pas actuellement
installées sur votre ordinateur. Vous ne pourrez donc pas les utiliser pour l'instant. Nous
aborderons ces types de programmes plus avancés plus tard dans le cours. Pour le
moment, notre concentration sera sur les applications de type "Console", car elles sont plus
appropriées à votre niveau actuel et ne nécessitent pas ces bibliothèques externes.
Cliquez sur le bouton "Go" pour initier la création du projet, ce qui ouvrira un assistant. La première page de
l'assistant n'est pas pertinente, donc passez à l'étape suivante en cliquant sur "Next" (Suivant). Vous serez alors
invité à choisir entre le langage C ou le langage C++. Optez pour "C++", comme présenté dans l'exemple ci-
dessous.

1.Nouveau projet C++


Ensuite, vous devrez nommer votre projet et préciser le dossier
où les fichiers source seront sauvegardés, comme l'illustre la Nom et dossier du projet
capture d'écran ci-dessous.
Sur la dernière page, vous pouvez sélectionner les options de compilation. Vous pouvez laisser
les paramètres par défaut, car cela n'aura pas d'impact immédiat sur ce que nous allons faire.
Assurez-vous simplement que "Debug" ou "Release" est coché.

Le mode de compilation
Dans le volet gauche intitulé "Projects", développez l'arborescence en cliquant sur le petit symbole
"+" pour voir la liste des fichiers dans le projet. Vous devriez trouver au moins un fichier nommé
"main.cpp", que vous pouvez ouvrir en double-cliquant dessus. Une fois cela fait, cliquez sur
"Finish", et voilà ! Code::Blocks a créé votre premier projet avec un peu de code source de base.
C'est tout ce qu'il faut faire !
Visual C++ (Windows seulement)

Quelques points à retenir concernant Visual C++ :


Il s'agit de l'IDE (Environnement de Développement Intégré) de Microsoft.
À l'origine, il était payant, mais Microsoft a publié une version gratuite appelée Visual C++ Express.

Quelles sont les différences avec le « vrai »


Visual ?

Il n'y a pas d'éditeur de ressources inclus


(pour la création d'images, d'icônes ou de
fenêtres) dans Visual C++ Express.
Cependant, cela ne sera pas un problème
pour nous, car ces fonctionnalités ne seront
pas nécessaires dans ce cours. Vous pouvez
trouver des instructions pour télécharger
Visual C++ Express.

Aperçu de Visual C++


Installation
Choisissez "Visual C++ Express Français" un peu plus bas sur la page. Visual C++ Express est disponible en
français et est complètement gratuit. Il ne s'agit pas d'une version d'essai limitée dans le temps. L'installation
devrait se dérouler normalement. Le programme d'installation téléchargera la dernière version de Visual C++
depuis Internet. Il est recommandé de laisser les options par défaut.

Lorsque vous terminez l'installation, il est mentionné qu'il faut s'enregistrer dans les 30
jours. Pas d'inquiétude, c'est gratuit et rapide, mais c'est nécessaire. Cliquez sur le lien
fourni, qui vous dirigera vers le site de Microsoft. Connectez-vous avec votre compte
Windows Live ID (similaire à un compte Hotmail ou MSN) ou créez-en un si vous n'en avez
pas. Ensuite, répondez au petit questionnaire. À la fin de cette procédure, vous obtiendrez
une clé d'enregistrement. Vous devrez copier cette clé dans le menu "Aide" > "Inscrire le
produit".
Créer un nouveau projet
Pour créer un nouveau projet sous Visual C++, suivez ces étapes :

1. Allez dans le menu "Fichier" (File) > "Nouveau" (New) > "Projet" (Project).
2. Dans la fenêtre de création de projet, sélectionnez "Win32" dans le panneau de gauche, puis
choisissez "Application" à droite.
3. Donnez un nom à votre projet, par exemple, "test".
Ajout d'un projet

Validez. Une nouvelle fenêtre s 'ouvre.


Assurez-vous que l'option "Projet vide" est cochée, comme illustré dans la figure suivante, puis cliquez sur
"Terminer"
Ajouter un nouveau fichier source
Votre projet est actuellement vide. Pour y ajouter un fichier source, faites un clic droit sur le dossier "Fichiers
sources" situé dans le volet de gauche, puis sélectionnez "Ajouter" > "Nouvel élément".

Ajout d'un nouvel élément


Dans la fenêtre qui s'ouvre, sélectionnez "Fichier C++ (.cpp)" comme type de fichier, puis entrez le nom
"main.cpp" pour votre fichier.

Ajout d'un fichier


Cliquez sur "Ajouter" pour confirmer. Vous êtes maintenant prêt à commencer à écrire du code
!La fenêtre principale de Visual
Voyons ensemble le contenu de la fenêtre principale de Visual C++ Express. Nous allons rapidement expliquer
la signification de chaque partie :

Fenêtre de Visual C++


1. La barre d'outils est assez standard, avec des options telles qu'Ouvrir, Enregistrer, Enregistrer
tout, Couper, Copier, Coller, etc. À noter qu'il n'y a pas de bouton de barre d'outils dédié à la
compilation par défaut, mais vous pouvez les ajouter en faisant un clic droit sur la barre d'outils,
puis en sélectionnant "Déboguer" et "Générer" dans la liste.
2. Toutes ces icônes liées à la compilation ont des équivalents dans les menus "Générer" et
"Déboguer". Par exemple, choisir "Générer" permet de créer l'exécutable (équivalent à "Compiler"
dans Visual C++). Si vous optez pour "Déboguer" > "Exécuter", il vous sera probablement
demandé de compiler avant d'exécuter le programme. Vous pouvez également utiliser les
raccourcis clavier, tels que F7 pour générer le projet et F5 pour l'exécuter.
La liste des fichiers du projet : dans cette zone très importante, vous voyez normalement la liste
des fichiers de votre projet. Cliquez sur l'onglet Explorateur de solutions, en bas , si ce n'est pas
déjà fait. Vous devriez voir que Visual crée déjà des dossiers pour séparer les différents types de
fichiers de votre projet (« sources », « en-têtes » et « ressources »). Nous verrons un peu plus
tard quels sont les différentes sortes de fichiers qui constituent un projet.
La zone principale : c'est là qu'on modifie les fichiers source.
La zone de notification : c'est là encore la « zone de la mort », celle où l'on voit apparaître toutes
les erreurs de compilation. C'est également dans le bas de l'écran que Visual affiche les
informations de débuggage quand vous essayez de corriger un programme buggé. Je vous ai
d'ailleurs dit tout à l'heure que j'aimais beaucoup le débugger de Visual et je pense que je ne suis
pas le seul. Voilà, on a fait le tour de Visual C++.
Vous pouvez aller jeter un œil dans les options (Outils > Options) si cela vous chante, mais n'y
passez pas 3 heures . Il faut dire qu'il y a tellement de cas es à cocher partout qu'on ne s ait plus
trop où donner de la tête.
Il existe plusieurs environnements de développement intégré (IDE) compatibles avec macOS. Code::Blocks en
est un exemple, mais ce n'est pas le seul. Je vais maintenant vous présenter l'IDE le plus renommé pour Mac :
Xcode.

"Où es-tu, Xcode ?"


Apple a bien compris que tous les utilisateurs de macOS ne sont pas des programmeurs. Par conséquent,
par défaut, macOS n'installe pas d'environnement de développement intégré (IDE). Cependant, pour ceux qui
souhaitent s'engager dans la programmation, Apple a prévu une solution. Xcode est inclus sur le CD
d'installation de macOS. Pour installer Xcode, suivez ces étapes : insérez le CD d'installation dans le lecteur,
ouvrez le paquet Xcode Tools situé dans le répertoire "Installation facultative" du disque d'installation. Cela
lancera l'installateur, comme illustré dans la figure suivante.

Installation de Xcode
En outre, je vous recommande de mettre en favori la page dédiée aux développeurs sur le site d'Apple. Vous y
trouverez une multitude d'informations précieuses pour le développement sur Mac, ainsi que la possibilité de
télécharger plusieurs logiciels pour développer. N'hésitez pas à vous inscrire à l'ADC (Apple Development
Connection), c'est gratuit, et cela vous permettra de rester informé des dernières nouveautés.

Lancement
L'application Xcode s e trouve dans le répertoire /Developer/Applications/ (figure s uivante).

Lancement de Xcode

Nouveau projet
Pour créer un nouveau projet, on clique sur Create a new Xcode project, ou File > New Project. Il faut choisir le
type Command Line Tool et sélectionner C++ /sdtc++ dans le petit menu déroulant (figure suivante).
Nouveau projet Xcode

Une fois le projet créé, la fenêtre principale de Xcode apparaît (suivante).


Fenêtre principale de Xcode
Vous pouvez ajouter de nouveaux fichiers C++ au projet via le menu File > New File.

Compilation
Le fichier "sdz-test" avec une icône noire est l'exécutable, tandis que le fichier "sdz-test.1" est un fichier de
documentation.

Le fichier "main.cpp" contient le code source du programme. Vous pouvez l'ouvrir en double-cliquant dessus.
Avant de compiler, vous devez effectuer un réglage dans les préférences de Xcode. Pour accéder aux
préférences, cliquez sur "Preferences" dans le menu Xcode. Dans l'onglet "debugging", sélectionnez "Show
console" dans la liste déroulante intitulée "On start". Cette manipulation est nécessaire pour afficher la sortie
d'un programme dans la console, comme illustré dans la figure suivante.
Options de Xcode
Cette manipulation n'a besoin d'être faite qu'une seule fois en tout.

Pour compiler, on clique sur le bouton Build and Run (en forme de marteau avec une petite icône verte
devant) dans la fenêtre du projet. La console s 'affiche alors (figure s uivante).
Compilation sous Xcode

Voilà ! Vous connaissez désormais l'essentiel pour créer un nouveau projet C++ et le compiler avec Xcode.
En résumé
Un IDE est un outil tout-en-un à destination des développeurs , qui permet de créer des
programmes . Un IDE est composé d'un éditeur de texte, d'un compilateur et d'un debugger.
Code::Blocks , Vis ual C++ et Xcode s ont parmi les IDE les plus connus pour programmer en
C++. Nous prendrons Code::Blocks comme bas e dans la s uite de ce cours .
Votre premier programme
Bonne nouvelle ! Le moment est enfin venu. Vous avez appris ce qu'est la programmation et les bases du
langage C++. Vous avez également installé un environnement de développement intégré (IDE) pour la
programmation. Maintenant, vous vous demandez : quand allons-nous commencer à écrire du code ?
Cependant, ne vous attendez pas à réaliser des projets complexes dès le début. La création de jeux en 3D en
temps réel sur un réseau n'est pas encore à l'ordre du jour ! Au lieu de cela, votre objectif dans ce chapitre est
de parvenir à afficher un simple message à l'écran. Vous allez bientôt découvrir que même cette tâche
apparemment simple nécessite un peu de travail !
§Le monde merveilleux de la console§
Quand je vous annonce que nous allons commencer à programmer, il est tout à fait naturel de penser :
"Super, je vais pouvoir réaliser tout ça, cela, et même ce projet dont j'ai toujours rêvé !" Cependant, il est de
mon devoir de tempérer un peu cette excitation et de vous expliquer comment nous allons procéder. Nous
allons débuter en douceur, car de toute évidence, nous n'avons pas d'autre choix. Les projets complexes en
3D sur réseau que vous pourriez imaginer nécessitent une base solide. Il est essentiel de comprendre qu'il
existe deux types de programmes : les programmes graphiques et les programmes console.

Nous allons commencer de manière progressive, car nous n'avons pas d'autre option. Les projets complexes
en 3D sur réseau que vous pourriez envisager nécessitent une compréhension des fondamentaux. Il est
important de noter qu'il existe deux types de programmes : les programmes graphiques et les programmes
console.
Les programmes graphiques
Ces programmes sont conçus pour afficher des fenêtres, ce qui est probablement familier pour vous. Ils
créent des interfaces visuelles à l'écran, permettant d'ouvrir, de réduire, de fermer et d'agrandir des fenêtres.
Dans le jargon des programmeurs, on les appelle des "GUI" pour "Graphical User Interface" (Interface
Utilisateur Graphique).

programme GUI (graphique) : Word


Les programmes console
Les programmes en console sont plus fréquents sous Linux que sous Windows et Mac OSX. Ils sont
constitués de simples textes qui s 'affichent à l'écran, le plus souvent en blanc sur fond noir (figure s uivante).

Un programme en console
Ces programmes fonctionnent au clavier. La souris n'est pas utilisée.
Ils s 'exécutent généralement linéairement : les messages s 'affichent au fur et à mesure, de haut en bas.
Notre première cible : les programmes console
Eh oui, j'imagine que vous l'avez vue venir, celle-là !
Je vous annonce que nous allons commencer par réaliser des programmes console. En effet, bien qu'ils soient
un peu austères a priori, ces programmes sont beaucoup plus simples à créer que les programmes graphiques
. Pour les débutants que nous sommes , il faudra donc d'abord en passer par là ! Bien entendu, je sais que vous
ne voudrez pas en rester là.
Soyez rassuré à ce sujet : je n'ai pas l'intention de m'arrêter aux programmes console, car je comprends que
beaucoup d'entre vous souhaitent créer des programmes graphiques. C'est une excellente nouvelle, car une
partie importante de ce cours sera consacrée à la création d'interfaces graphiques utilisateur (GUI) avec Qt,
une extension du langage C++ qui permet de développer ce type de programmes. Cependant, avant d'arriver
à cela, il est temps de retrousser nos manches et de se mettre au travail. Alors, en avant !
Nous avons déjà installé un environnement de développement intégré (IDE), cet outil essentiel qui contient tout
ce dont vous avez besoin pour programmer. Nous avons également constaté qu'il existe plusieurs IDE
populaires, dont Code::Blocks, Visual C++, Xcode, pour n'en mentionner que quelques-uns, mais il en existe
bien d'autres !

Comme je l'avais mentionné précédemment, je me concentrerai principalement sur l'utilisation de


Code::Blocks dans mes explications. Cependant, je reviendrai sur d'autres environnements de
développement si cela s'avère nécessaire. Heureusement, la plupart de ces logiciels ont des similitudes
marquées et utilisent un vocabulaire commun. Ainsi, quelle que soit l'IDE que vous utilisez, vous ne devriez
pas vous sentir perdu.

Création d'un projet


Pour débuter la programmation, la première étape consiste à demander à votre environnement de
développement intégré (IDE) de créer un nouveau projet. C'est un peu similaire à demander à Microsoft Word
de créer un nouveau document.
Pour cela, suivez la séquence de menus File > New > Project. Un assistant apparaîtra, comme nous
l'avons vu dans le chapitre précédent. Créez un nouveau programme console en langage C++,
comme nous l'avons appris précédemment.

Une fois que vous avez terminé les étapes de l'assistant, le projet sera créé, et il contiendra un
premier fichier. Dépliez l'arborescence à gauche pour afficher le fichier "main.cpp", puis double-
cliquez dessus pour l'ouvrir. Ce fichier est notre premier code source, et il est déjà partiellement
rempli, comme indiqué dans la figure suivante.

Premier programme dans Code::Blocks


Code::Blocks a généré un premier programme très simple qui affiche à l'écran le message : "Hello world!"
("Bonjour tout le monde !").

Il y a déjà une dizaine de lignes de code s ource C++ et je n'y comprends rien !

Je comprends que cela puisse sembler un peu complexe la première fois, mais ne vous inquiétez pas. Plus
tard dans le cours, nous examinerons ensemble en détail ce que signifie ce code et comment il fonctionne.

Lancement du programme
Pour l'instant, je vous encourage à faire quelque chose de simple : essayez de compiler et d'exécuter ce
premier programme. Vous vous rappelez comment procéder ? Il y a un bouton "Compiler et exécuter" (Build
and run) situé dans la barre d'outils, comme illustré dans la figure suivante.

Les boutons de compilation

Lorsque vous lancez la compilation, vous verrez apparaître quelques messages en bas de l'IDE,
dans la section "Build log".
Si la compilation échoue et que vous obtenez une erreur du type : "My-program - Release" utilise
un compilateur invalide. Skipping… Nothing to be done. Cela signifie que vous avez téléchargé la
version de Code::Blocks sans le compilateur Mingw. Dans ce cas, retournez sur le site de
Code::Blocks et téléchargez la version avec Mingw.
Si tout se passe comme prévu, une console s'affiche avec notre programme, comme indiqué dans la figure
suivante.

Premier programme en console


Vous pouvez voir que le programme affiche effectivement "Hello world!" dans la console ! N'est-ce pas
satisfaisant ? Vous venez de compiler votre tout premier programme avec succès !

Un fichier exécutable a été généré sur votre disque dur. Sous Windows, il s'agit d'un fichier
.exe. Vous pouvez le trouver dans un sous-dossier "release" (ou parfois "debug"), situé dans le
répertoire "bin" de votre projet.
Au fait, que signifie le message à la fin de la console : « Process returned 0 (0x0)
execution time :0.004 s Press any key to continue. » ?

C'est une excellente question ! Ce message n'a pas été généré par votre programme, mais
par votre IDE. En l'occurrence, Code::Blocks affiche ce message pour indiquer que le
programme s'est bien exécuté et pour donner des informations sur la durée de son
exécution.
Le principal objectif de Code::Blocks dans ce contexte est de maintenir ouverte la console. En
effet, particulièrement sous Windows, dès qu'un programme console se termine, la fenêtre de
la console se ferme automatiquement. Dans ce cas, le programme s'est exécuté en seulement
0,004 seconde, ce qui signifie que vous n'auriez pas eu le temps de voir le message s'afficher à
l'écran si la console se fermait immédiatement.

Code::Blocks vous invite donc à "appuyer sur n'importe quelle touche pour continuer", et
cette action aura pour effet de fermer la console.
Lorsque vous compilez et exécutez un programme "console" avec Visual C++, la console a tendance à s'ouvrir
et se refermer instantanément, contrairement à Code::Blocks qui maintient la console ouverte. Si vous utilisez
Visual C++, une solution consiste à ajouter la ligne system("PAUSE"); juste avant la ligne return 0; de votre
programme. Cette ligne permettra de faire une pause et de maintenir la console ouverte jusqu'à ce qu'une touche
soit pressée.
Explications sur ce premier code source

Lors que Code::Blocks crée un nouveau projet, il génère


un fichier main.cpp contenant ce code :
Code : C++
#include <iostream>
using namespace std;
int main()
{
cout << "Hello world!" << endl;
return 0;
}
Sans plonger dans les détails, afin de ne pas compliquer les choses pour les débutants, je vais vous
expliquer la fonction de chaque ligne.

La plupart des environnements de développement intégré (IDE) proposent généralement de commencer avec un
code similaire, ce qui permet de démarrer la programmation plus rapidement. Les trois premières lignes (include,
using namespace, et int main) se retrouveront dans presque tous vos programmes en C++. Vous pouvez considérer
que ces lignes seront présentes au début de tous vos programmes.
La toute première ligne es t : #include <iostream>

eci est ce qu'on appelle une directive de préprocesseur. Son rôle est de "charger" des fonctionnalités
du langage C++ afin que nous puissions effectuer certaines actions.

Le langage C++ est très modulaire. À la base, il ne possède pas de fonctionnalités étendues (il ne peut
même pas afficher un simple message à l'écran !). Par conséquent, nous devons charger des extensions
appelées bibliothèques pour obtenir de nouvelles fonctionnalités. Dans ce cas, nous chargeons le fichier
iostream, ce qui nous permet d'utiliser une bibliothèque pour afficher des messages à l'écran dans une
console. C'est quelque chose de très basique, comme vous pouvez le constater, mais qui nécessite
néanmoins l'utilisation d'une bibliothèque.
Inclure iostream dans notre programme nous offre davantage que la simple capacité d'afficher des
messages à l'écran. Plus tard, nous verrons qu'il nous permettra également de récupérer les saisies de
l'utilisateur depuis le clavier. iostream est l'acronyme de "Input Output Stream", ce qui signifie "Flux
d'entrée-sortie". Dans le contexte d'un ordinateur, l'entrée est généralement associée au clavier ou à
la souris, tandis que la sortie concerne l'affichage à l'écran. En incluant iostream, nous obtenons
essentiellement les éléments nécessaires pour interagir avec l'utilisateur en termes d'échanges
d'informations.
Plus tard, nous découvrirons de nouvelles bibliothèques et il faudra effectuer des inclusions en haut des
codes s ource comme ici. Par exemple, lors que nous étudierons Qt, qui permet de réaliser des programmes
graphiques (GUI), on insérera une ligne comme celle-ci :
Code : C++
• #include <Qt>
Il est important de noter qu'il est possible de charger autant de bibliothèques que nécessaire en même
temps. La ligne de code que vous voyez permet en quelque sorte d'indiquer dans quel ensemble de
fonctionnalités notre fichier source puisera.
• using namespace
std;
Lorsque vous chargez plusieurs bibliothèques, chacune peut offrir de nombreuses
fonctionnalités. Parfois, certaines de ces fonctionnalités portent le même nom. Par exemple,
imaginez une commande "AfficherMessage" qui existe à la fois dans iostream et dans Qt. Si
vous chargez les deux bibliothèques simultanément et appelez "AfficherMessage",
l'ordinateur ne saura pas s'il doit afficher un message dans la console avec iostream ou dans
une fenêtre avec Qt.
Pour éviter ce type de conflits, des espaces de noms (namespace) ont été créés. Les espaces
de noms sont en quelque sorte des dossiers portant des noms. La ligne "using namespace
std;" indique que vous allez utiliser l'espace de noms "std" dans la suite de votre fichier
source. "std" est l'un des espaces de noms les plus couramment utilisés, car il correspond à
la bibliothèque standard (std), qui est livrée par défaut avec le langage C++ et inclut iostream.
En utilisant "std::" devant les éléments de la bibliothèque standard, vous évitez les conflits de
noms avec d'autres bibliothèques.
C'est à ce moment que le cœur du programme commence à battre.
int main() Une fonction a la forme s uivante : Les programmes, comme vous le découvrirez, sont principalement
int main() constitués de fonctions. Chaque fonction a un objectif particulier
et peut appeler d'autres fonctions pour accomplir des tâches
{ spécifiques.
Tous les programmes incluent une fonction nommée "main" (qui
} se prononce "mèïne" en anglais), ce qui signifie "principale". Il
s'agit donc de la fonction principale du programme.
Les accolades délimitent le début et la fin de la fonction. Comme vous pouvez le constater dans le code source
généré par Code::Blocks, il n'y a rien après la fonction main. C'est normal : à la fin de la fonction main, le
programme s'arrête ! En d'autres termes, tout programme commence son exécution au début de la fonction
main et la termine à la fin de cette fonction.

Cela veut dire qu'on va écrire tout notre programme dans la fonction main ?
Je m'excuse pour la confusion. Vous avez raison, dans la plupart des cas, la fonction main appelle d'autres
fonctions qui, à leur tour, peuvent appeler d'autres fonctions, créant ainsi une structure en cascade. C'est une
approche beaucoup plus gérable, en particulier pour les programmes plus complexes.
Cependant, dans un premier temps, nous nous concentrerons principalement sur la fonction main, car nos
programmes resteront relativement simples pour le moment.
• cout
Enfin, nous arrivons à la première ligne de code qui accomplit une tâche concrète ! Il s'agit de la première
ligne de la fonction main, donc c'est la première action qui sera exécutée par l'ordinateur. Les lignes que
nous avons vues précédemment étaient en réalité des préparatifs pour le programme.
Code : C++
cout << "Hello world!" << endl;
La fonction de cout (prononcée "ci aoute") est d'afficher un message à l'écran. C'est ce que l'on appelle une
instruction. Tous nos programmes seront composés d'instructions similaires à celle-ci, qui donnent des
instructions à l'ordinateur. Il est important de noter que cout est fourni par la bibliothèque iostream. Si vous
n'incluez pas iostream au début de votre programme, le compilateur signalera une erreur car il ne
reconnaîtra pas cout, et vous ne pourrez pas générer votre programme.

Il est essentiel de noter que chaque instruction se termine par un point-virgule ! C'est en effet ce
qui permet de distinguer les instructions du reste du code. Si vous oubliez le point-virgule, la
compilation échouera, et votre programme ne pourra pas être créé.
Sur la ligne de code que vous avez montrée, il y a trois éléments importants :
• cout : cette commande indique à l'ordinateur d'afficher un message à l'écran.
• "Hello world!" : c'est le message à afficher. Il est contenu entre des guillemets.
• endl : cela crée un retour à la ligne dans la console, ce qui signifie que le texte suivant sera affiché sur une
nouvelle ligne.
Il est possible de combiner plusieurs messages en une seule instruction. Par exemple :
Code : C++
cout << "Bonjour tout le monde !" << endl << "Comment allez-vous ?"
<< endl;
… affiche ces deux phrases sur deux lignes différentes . Essayez ce code, vous verrez !
Sous Windows, les caractères accentués peuvent s'afficher de manière incorrecte (essayez d'afficher
"Bonjour à vous LIM2" pour voir !). C'est un problème lié à la console de Windows (qui peut également se
produire plus rarement sous Mac OS X et Linux). Bien qu'il existe des moyens de le résoudre, aucun n'est
vraiment satisfaisant. À la place, je vous recommande d'éviter d'utiliser des caractères accentués dans les
programmes console sous Windows.Cependant, soyez rassuré : les interfaces graphiques utilisateur (GUI)
que nous créerons plus tard avec Qt ne seront pas affectées par ce problème !
Pour être sûr de bien comprendre ce qui se passe, je vous encourage à créer vos propres exemples et à afficher ce
qui vous vient à l'esprit. N'oubliez pas d'utiliser endl pour effectuer des retours à la ligne, et de séparer chaque
morceau de texte par les opérateurs <<. D'ailleurs, vous devriez être fier de ces essais, car ce sont les premiers
programmes C++ que vous réalisez tout seul, sans simplement copier depuis un cours ! Je vous conseille de
suivre cette approche tout au long de ce cours. Chaque fois qu'il y aura des exemples, essayez de modifier les
instructions, observez ce qui se passe en changeant l'ordre, bref, expérimentez. C'est le meilleur moyen
d'apprendre.
Pendant vos expérimentations, vous avez peut-être tenté d'afficher un caractère d'antislash () ou des
guillemets ("). Si ce n'est pas le cas, je vous encourage à le faire maintenant :

#include <iostream> Code : C++


using namespace std;

int main()
{
cout << "Je fais des tests pour apprendre le C++ !" << endl;
cout << """ << endl;
cout << "\" << endl;
return 0;
}
Le compilateur n'appréciera pas du tout cela, et un message d'erreur devrait s'afficher dans la zone en bas
de votre fenêtre Code::Blocks. La raison en est simple : pour afficher des guillemets, il faut utiliser la
combinaison " et non simplement ". De même, pour le caractère d'antislash, il faut le doubler. Vous devez
donc écrire :
Code : C++

#include <iostream>
using namespace std;
int main()
{
cout << "Je fais des tests pour apprendre le C++ !" << endl;
cout << "\"" << endl;
cout << "\\" << endl;
return 0;}
Je vous invite à effectuer le test pour vérifier que cela fonctionne. Maintenant que vous avez pris
connaissance de ces deux petites exceptions, vous êtes prêt à afficher tout ce qui vous passe par la tête
dans la console. Regardons maintenant ce qui se passe à la fin de notre programme.

• return Code : C++


La dernière ligne es t : return 0;

Ce type d'instruction clôture généralement les fonctions. En réalité, la plupart des fonctions renvoient
une valeur, généralement un nombre. Dans ce cas, la fonction main renvoie 0 pour indiquer que tout
s'est bien déroulé (toute valeur différente de 0 aurait indiqué un problème).
Vous n'avez pas besoin de modifier cette ligne, laissez-la telle quelle. Nous aurons d'autres occasions
d'utiliser "return" pour d'autres fonctions, et nous en reparlerons !
Commentez et mettez en forme vos programmes !
Un autre aspect important de la programmation est la documentation et la mise en forme de vos
programmes. En plus du code qui donne des instructions à l'ordinateur, vous pouvez écrire des
commentaires pour expliquer le fonctionnement de votre programme. Les commentaires n'ont aucun impact
sur le fonctionnement de votre logiciel ; en fait, le compilateur ne les lit même pas, et ils n'apparaissent pas
dans le programme généré. Cependant, ces commentaires sont indispensables pour les développeurs. Ils
permettent d'expliquer ce que fait le code.
Lorsque vos programmes deviennent un peu plus complexes, il devient difficile de se souvenir de leur
fonctionnement quelques temps après avoir écrit le code source. De plus, si vous partagez votre code avec
un ami ou un collègue, il pourrait avoir du mal à comprendre ce que vous avez essayé de faire en lisant
simplement le code source. C'est là que les commentaires jouent un rôle essentiel !
• Les différents types de commentaires
Il existe deux façons d'écrire des commentaires en fonction de leur longueur. Je vais vous
présenter les deux méthodes.

Les commentaires courts


Pour écrire un commentaire court, sur une seule ligne, il suffit de commencer par // suivi de votre
commentaire. Voici un exemple :
Si votre commentaire s'étend sur plusieurs lignes, vous pouvez ouvrir la zone de commentaire avec /* et la
fermer avec */
Code : C++
cout << "Hello world!" << endl; // Affiche un message à l'écran
Les commentaires longs // Ceci est un commentaire

En général, il est préférable de ne pas écrire un commentaire excessivement long non plus, à
moins que la situation ne le justifie vraiment. Reprenons le code source que nous avons étudié
dans ce chapitre et ajoutons quelques commentaires pour expliquer ce qu'il fait et nous aider à
nous en souvenir.
Commentons notre code source !
/* Le code qui suit est un peu complexe, prenons le temps de
l'expliquer en détail, car je sais que sinon, dans quelques
semaines, j'aurai tout oublié et je serai perdu si je dois le
modifier. */
Code : C++
#include <iostream> // Inclut la bibliothèque iostream (affichage de
texte)
using namespace std; // Indique quel espace de noms on va utiliser
/*
Fonction principale "main"
Tous les programmes commencent par la fonction main
*/
int main()
{
cout << "Hello world!" << endl; // Affiche un message
return 0; // Termine la fonction main et donc le programme
}
En exécutant ce programme, vous ne remarquerez aucune différence. Les commentaires, comme je
vous l'ai expliqué précédemment, sont complètement ignorés par le compilateur.
J'ai délibérément commenté chaque ligne de code ici, mais en pratique, il ne faut pas non plus abuser
des commentaires. Si une ligne de code fait quelque chose d'évident, il est inutile de la commenter. En
réalité, les commentaires sont plus utiles pour expliquer le fonctionnement d'une série d'instructions
plutôt que chaque instruction individuellement.

Mettre son code en forme


La mise en forme du code est cruciale pour les développeurs. Le compilateur ne se soucie pas des espaces ni
des retours à la ligne dans le code source. Ces éléments de mise en forme sont conçus pour améliorer la
lisibilité humaine. Le compilateur peut toutefois traiter un code sans mise en forme, mais cela le rendra très
difficile à lire pour les développeurs. Par conséquent, nous utilisons des espaces, des retours à la ligne et une
mise en forme adéquate pour rendre notre code plus lisible.
Code : C++

#include <iostream>
using namespace std; int main()
{
cout << "Hello world!"<< endl; return 0; }
Bien sûr, essayez pour voir ! Cependant, il est évident que ce code est loin d'être facile à lire. Les
paires de parenthèses ne sont pas clairement visibles, la séparation entre les instructions est floue, ce qui
rend ce code source peu convivial.
Maintenant, imaginez que votre programme ait des centaines de lignes, cela deviendrait
rapidement incompréhensible. Pour éviter ce chaos, il est essentiel de formater votre code de manière
lisible. Heureusement, Code::Blocks propose un outil pour vous aider dans cette tâche. Vous pouvez ouvrir
le menu "Plugins" et sélectionner "Source code formatter (AStyle)" pour que votre code se mette
automatiquement en forme, devenant ainsi plus lisible.
Notez que cette mise en forme n'affecte pas le comportement du compilateur, mais elle facilite
grandement la lecture pour vous et vos collègues travaillant sur le même projet. À mesure que vous
progresserez dans ce cours, vous comprendrez l'importance d'avoir un code correctement formaté et bien
commenté.

En résumé :
Il existe deux types de programmes : les programmes graphiques (GUI) et les programmes
console.
Pour commencer, il est plus simple de créer des programmes console, c'est donc le type de programme
que nous étudierons en premier.
Chaque programme possède une fonction principale main() qui est son point de départ.
La directive cout est utilisée pour afficher du texte dans une console.
Vous pouvez ajouter des commentaires dans votre code source pour expliquer son fonctionnement. Les
commentaires prennent la forme // pour les commentaires courts.
Jusqu'à présent, vous avez appris à créer et compiler des programmes en mode console. Ces
programmes étaient très simples, se contentant d'afficher des messages à l'écran, et c'est à peu près tout.

La simplicité de ces programmes s'explique par le fait qu'ils ne sont pas encore capables
d'interagir avec l'utilisateur. Dans le prochain chapitre, vous apprendrez à réaliser cette interaction.
Cependant, avant d'aller plus loin, nous devons aborder un concept fondamental en informatique : les
variables. Les variables permettent d'utiliser la mémoire de l'ordinateur pour stocker des informations et
les récupérer ultérieurement.

Pensez à une calculatrice que vous avez peut-être déjà utilisée. Elle dispose souvent de touches
telles que M+, M-, MC, etc., qui servent à stocker temporairement le résultat d'un calcul en mémoire pour
une utilisation future. Nous allons apprendre à faire quelque chose de similaire avec votre ordinateur, qui
n'est, après tout, qu'une machine de calcul beaucoup plus puissante.

Mais qu'est-ce qu'une variable exactement ? L'exemple de la mémoire de la calculatrice est


pertinent ici, car le principe de base en informatique est similaire. Votre ordinateur contient des
composants électroniques capables de stocker une valeur et de la conserver pendant un certain temps. Le
fonctionnement précis de tout cela est très complexe, mais rassurez-vous, vous n'avez pas besoin de le
comprendre en détail pour utiliser des variables. Le compilateur et le système d'exploitation se chargeront
de la gestion technique complexe.
Utiliser la mémoire
La seule et unique chose que vous devez retenir, c'est que, en informatique, une variable est un espace
dans la mémoire de l'ordinateur que l'on peut utiliser pour stocker des valeurs.
Imaginez que l'ordinateur dispose d'une immense armoire dans ses entrailles (comme illustré dans la
figure). Cette armoire est équipée de milliers, voire de milliards de petits tiroirs, et chacun de ces tiroirs
peut être utilisé pour stocker une variable. La mémoire de l'ordinateur peut être comparée à une énorme
armoire remplie de tiroirs.

Dans le cas d'une calculatrice simple, vous ne pouvez généralement stocker qu'un seul nombre à la fois.
Cependant, dans un programme informatique, vous devez souvent conserver simultanément plusieurs
valeurs. C'est pourquoi chaque variable doit avoir un nom unique, comme une étiquette sur un tiroir, pour
pouvoir y accéder ultérieurement. De plus, contrairement à une calculatrice, les ordinateurs peuvent
stocker une variété de données telles que des nombres, des lettres, des phrases, des images, etc. C'est ce
qu'on appelle le "type" d'une variable, qui peut être comparé à la forme du tiroir dans lequel vous rangez
vos objets. Commençons par aborder la question des noms de variables. En C++, il existe des règles pour
définir quels noms de variables sont autorisés ou interdits.
Les noms de variables
En C++, voici les règles pour nommer les variables :
1. Les noms de variables sont constitués de lettres, de chiffres et du tiret-bas (_) uniquement.
2. Le premier caractère doit être une lettre (majuscule ou minuscule).
3. Les accents ne sont pas autorisés.
4. Les espaces ne peuvent pas être utilisés dans le nom.
Des exemples concrets clarifieront la situation. Des noms tels que "ageZero", "nom_du_zero", ou
même "NOMBRE_ZEROS" sont parfaitement valides en C++. En revanche, des noms comme "AgeZéro"
ou "_nomzero" ne sont pas autorisés.
En plus de ces règles, il y a une règle importante qui s'applique à tout le code en C++, pas seulement aux
noms de variables : le langage distingue entre majuscules et minuscules. En d'autres termes, le C++ est
sensible à la casse. Ainsi, "nomZero", "nomzero", "NOMZERO", et "NomZeRo" seraient tous considérés
comme des noms de variables distincts.

Il est essentiel d'utiliser des noms de variables significatifs pour améliorer la lisibilité de votre code.
Optez donc pour des noms comme "ageUtilisateur" plutôt que des noms génériques comme "maVar"
ou "variable1". Bien que cela n'ait aucune incidence sur le fonctionnement du compilateur, cela facilite
grandement la compréhension de votre code pour vous et vos collaborateurs.
Je préfère suivre une "convention" couramment utilisée par de nombreux programmeurs.
Dans les grands projets qui impliquent de nombreux développeurs, il existe souvent des règles
strictes, parfois complexes à respecter. Cependant, les règles que je vais vous présenter sont
conçues pour maintenir une lisibilité optimale et vous aider à comprendre facilement les exemples
à venir dans ce cours. Les noms de variables commencent par une lettre minuscule. Si le nom est
composé de plusieurs mots, ils sont écrits en attaché, et chaque nouveau mot (à l'exception du
premier) commence par une majuscule.
Reprenons cet exemple : si vous avez une variable qui doit stocker l'âge de l'utilisateur du
programme, vous pourriez l'appeler "ageUtilisateur" en suivant la convention. Cela rend le code
plus lisible et compréhensible pour vous et d'autres développeurs qui pourraient travailler sur le
même programme.
C'est tout à fait correct. Le nom "ageUtilisateur" est le choix approprié selon la convention
que vous avez présentée. Cela rend le nom de la variable descriptif, facile à lire et à comprendre. Il
commence par une minuscule, les mots sont collés, et chaque nouveau mot (à l'exception du
premier) commence par une majuscule.
En effet, avoir deux variables avec le même nom dans la même fonction serait une
source de confusion pour le compilateur et le programmeur. Chaque variable doit avoir
un nom unique à l'intérieur d'une fonction pour éviter toute ambiguïté. C'est une règle
fondamentale pour écrire un code propre et compréhensible.
Je recommande vivement d'appliquer la même norme. Assurer la lisibilité et la compréhension aisée
du code par d'autres développeurs revêt une grande importance, et cela ne se limite pas seulement à
la mise en forme.
Les types de variables
Recommençons. Nous avons acquis la notion qu'une variable se compose d'un nom et d'un type.
Nous avons appris à attribuer des noms à nos variables, et maintenant, explorons les différents
types de données disponibles. Il est essentiel d'indiquer à l'ordinateur le type d'information que la
variable va stocker. Est-ce un nombre, un texte, une lettre ? Cette information doit être spécifiée.
Voici donc la lis te des types de variables que l'on peut utilis er en C++.
Nom du Type Ce qu’il faut contenir
char Un caractère.
bool Une valeur parmi deux pos s ibles , vrai (true) ou
faux (false).

int Un nombre entier.

unsigned int Un nombre entier positif ou nul.


Nom du Type Ce qu’il faut contenir
float Un nombre à virgule.
string Une chaîne de caractères , c'es t-à-dire un mot ou une
phrase.

Lorsque vous saisissez l'un de ces noms de types dans votre environnement de développement intégré
(IDE), vous devriez remarquer que le mot se met en surbrillance, indiquant que l'IDE l'a reconnu. Cependant,
le cas du type "string" est différent, et nous explorerons plus en détail la raison derrière cela plus tard. Je
peux vous assurer que nous reviendrons souvent sur ce point.
Ces types de données comportent des limites de validité, ce qui signifie qu'ils ont des valeurs minimales et
maximales. Ces limites sont déterminées par votre ordinateur, votre système d'exploitation et votre compilateur. Il
est important de noter que pour la plupart des utilisations courantes, ces limites sont généralement suffisamment
élevées et ne devraient pas poser de problème. Toutefois, des contraintes peuvent se présenter si vous envisagez de
développer des applications pour des appareils tels que des téléphones portables ou des microcontrôleurs, qui ont
parfois des limites plus strictes que les ordinateurs conventionnels. Il existe également d'autres types de données
moins fréquemment utilisés avec des limites différentes.
Quand on a besoin d'une variable, il faut donc se poser la question du genre de choses qu'elle va contenir. Si
vous avez besoin d'une variable pour stocker le nombre de personnes qui utilisent votre programme, alors
utilisez un int ou unsigned int, ; pour stocker le poids d'un gigot, on utilisera un double et pour
conserver en mémoire le nom de votre meilleur ami, on choisira une chaîne de caractères string.
Mais à quoi s ert le type bool ? Je n'en ai jamais entendu parler.
Un booléen est une variable qui ne peut avoir que deux valeurs, soit vrai (true en anglais) soit faux (false en
anglais). Ils sont couramment utilisés pour stocker des informations telles que l'état de la lumière, les
autorisations d'accès à une fonctionnalité ou la vérification d'un mot de passe. Si vous avez besoin de
conserver le résultat d'une question de ce genre, les variables booléennes sont une option à considérer.

Passons maintenant à la déclaration de variables. En d'autres termes, il est temps de demander à


l'ordinateur de réserver un espace de stockage pour nous, ce que l'on appelle techniquement la
"déclaration de variable".
Pour déclarer une variable, il est essentiel d'indiquer à l'ordinateur trois éléments : son type, son nom et
enfin, sa valeur. Cette procédure est très simple et se fait en respectant l'ordre présenté dans la figure
suivante.
La syntaxe pour initialiser une variable en C++ est similaire à celle
du langage C. Vous pouvez utiliser la même syntaxe que celle
présentée dans la figure suivante.
Syntaxe d'initialisation d'une variable, héritée du C
Les deux versions sont totalement équivalentes. Néanmoins, il est recommandé d'opter pour la première
version, car les raisons pour ce choix deviendront plus claires au fur et à mesure de notre progression
dans le cours. La deuxième version ne sera pas utilisée par la suite, mais je l'ai présentée ici pour vous
permettre de comprendre les nombreux exemples que l'on peut trouver en ligne, qui utilisent cette forme de
déclaration de variable.
À partir de ce point, vous êtes maintenant le
Code : C++ propriétaire d'un espace de stockage dans la
mémoire de l'ordinateur, comme illustré dans la
figure suivante.
#include <iostream>
using namespace std; Un tiroir dans la mémoire de l'ordinateur
contenant le chiffre 16
int main()
{ Étant donné que nous aurons besoin d'un grand nombre
d'espaces de stockage tout au long du cours, je vous
int ageUtilisateur(16); suggère d'utiliser des schémas plus simples comme ceux
présentés dans la figure suivante. Nous les utiliserons
return 0; fréquemment à l'avenir, il est donc judicieux de s'y
familiariser dès maintenant.
}
À la ligne 6 de ce programme, l'ordinateur identifie que
nous souhaitons réserver un espace de stockage dans
sa mémoire avec les caractéristiques suivantes :

• Il peut contenir des nombres entiers (entiers)


• Il est identifié par l'étiquette "ageUtilisateur"
• Il est initialement attribué avec la valeur 16.
Je comprends bien. Le gros rectangle bleu représente la mémoire de l'ordinateur, qui est actuellement
presque vide. Le carré jaune symbolise la zone de mémoire que l'ordinateur nous a allouée, équivalente à
notre tiroir. À l'intérieur, il contient toujours la valeur 16, et l'étiquette "ageUtilisateur" est attachée à ce tiroir
pour l'identifier. Je vois où vous voulez en venir, continuons donc en déclarant d'autres variables.

Code : C++

#include <iostream>
using namespace std;

int main()
{
int ageUtilisateur(16);
int nombreAmis(432); //Le nombre d'amis de l'utilisateur

double pi(3.14159);
bool estMonAmi(true); //Cet utilisateur est-il mon Il est toujours judicieux d'ajouter un
ami ? commentaire expliquant l'objectif de la
char lettre('a'); variable.
Vous pouvez certainement compléter votre schéma en y ajoutant les nouvelles
return 0;
}
variables, comme illustré dans la figure suivante. Cela rendra plus claire la
représentation de la mémoire de l'ordinateur avec l'ajout de ces nouvelles variables.
Schéma de l'état de la
mémoire après plusieurs
déclarations

Votre programme effectue plusieurs étapes :

1. Il demande au système d'exploitation de lui allouer de la mémoire.


2. Le système d'exploitation vérifie la disponibilité de la mémoire et indique au programme quels espaces de
stockage utiliser.
3. Le programme écrit la valeur 16 dans ces emplacements mémoire.
4. Cette opération est répétée pour les quatre autres variables.
5. En atteignant la dernière ligne, le programme libère les espaces mémoire et les restitue à l'ordinateur.
Il est important de noter que rien n'est affiché à l'écran, car aucune instruction n'a été donnée pour cela.
Le cas des strings
Pour déclarer des chaînes de caractères, il y a quelques étapes à suivre, mais rassurez-vous, ce n'est pas
insurmontable. Tout d'abord, au début de votre programme, vous devez ajouter une ligne pour indiquer au
compilateur que vous avez l'intention d'utiliser des chaînes de caractères. C'est essentiel car cela permettra
au compilateur d'inclure les outils nécessaires à leur gestion. La ligne à ajouter ressemble à ceci : [insérer la
ligne ici].(S'il vous plaît, insérez la ligne spécifique que vous avez en tête, car elle n'a pas été fournie dans
votre texte.)
La différence importante réside dans la manière dont vous
Code : C++ déclarez une chaîne de caractères. Comme vous avez sûrement
#include <string> remarqué, j'ai entouré la valeur par des guillemets doubles (")
#include <iostream> plutôt que des apostrophes (') comme pour les caractères
individuels (char). Vous devriez également remarquer que votre
#include <string> environnement de développement intégré (IDE) colorie
using namespace std; probablement le texte "Albert Einstein" d'une couleur différente
par rapport au 'a' de l'exemple précédent.
int main()
{ Il est crucial de ne pas confondre les guillemets doubles et les
apostrophes, car cela peut provoquer des erreurs de
string nomUtilisateur("Albert
compilation. C'est une erreur courante, mais ne vous inquiétez
Einstein"); pas, le compilateur est habitué à en voir de toutes les couleurs.
return 0;
}
Une astuce pour gagner de la place
Avant de passer à la suite, permettez-moi de vous présenter une petite astuce utilisée par certains
programmeurs. Si vous avez plusieurs variables du même type à déclarer, vous pouvez le faire sur une seule
ligne en les séparant par une virgule (,). Voici comment :

Code : C++ Déclaration d'une variable sans initialisation

int a(2),b(4),c(-1); //On


Et sous forme de code C++ complet, voilà ce que cela
déclare trois cases mémoires
donne :
nommées a, b et c et qui
Code : C++ #include <iostream>
contiennent respectivement
#include <string>
les valeurs 2, 4 et -1
using namespace std;
string prenom("Albert"),
nom("Einstein"); //On int main()
déclare deux cases pouvant {
contenir des chaînes de string nomJoueur;
caractères int nombreJoueurs;
bool aGagne; //Le joueur a-t-
il gagné ?

return 0;
}
Cela peut s'avérer pratique lorsque vous avez besoin de déclarer de nombreuses variables du même type en
une seule fois. Cela évite la répétition du type à chaque déclaration. Cependant, je vous conseille de ne pas en
abuser, car cela peut rendre votre programme moins lisible et moins compréhensible. Il est essentiel de trouver
un équilibre entre la concision et la clarté dans votre code.
Déclarer sans initialiser

Maintenant que nous avons exploré le concept général, il est temps d'approfondir un peu plus les détails.
Lorsque vous déclarez une variable, votre programme réalise en réalité deux opérations consécutives :
Il demande à l'ordinateur de lui allouer un espace de stockage dans la mémoire, ce que l'on appelle l'allocation
de la variable.
Ensuite, il remplit cette zone avec la valeur fournie, ce qui correspond à l'initialisation de la variable. Ces deux
étapes se déroulent automatiquement sans que l'utilisateur ait besoin d'intervenir.
Cependant, il peut arriver que vous ne sachiez pas quelle valeur attribuer à une variable lors de sa déclaration.
Dans ce cas, il est possible d'effectuer uniquement l'allocation sans l'initialisation. Vous indiquez simplement le
type et le nom de la variable sans spécifier de valeur, comme illustré dans la figure suivante.
Une erreur courante consiste à ajouter des parenthèses vides après le nom de la variable,
par exemple : "int nombreJoueurs()". C'est incorrect, il ne faut pas inclure de parenthèses, il
suffit d'indiquer le type suivi du nom de la variable.
En effet, c'est assez simple, et j'apprécie votre explication claire. De plus, un schéma en bonus
serait très utile pour une compréhension visuelle encore meilleure. Je serais ravi de voir votre
schéma pour mieux illustrer les concepts que vous avez expliqués.
C'est une excellente illustration visuelle ! Dans votre schéma, on peut clairement voir que vous avez alloué
trois variables sans les initialiser, ce qui signifie que ces trois cases mémoire existent, mais leur contenu est
inconnu. Dans le prochain chapitre, nous explorerons comment modifier le contenu d'une variable pour
La

remplacer ces points d'interrogation par des valeurs plus significatives.


Il est en effet recommandé de toujours initialiser vos variables pour éviter des comportements
indéterminés et des bogues potentiels dans votre programme. Ce que vous avez montré
concernant la déclaration sans initialisation devrait être réservé aux cas exceptionnels où l'on ne
sait vraiment pas quelle valeur attribuer à la variable, ce qui est en effet rare. L'initialisation
appropriée des variables contribue à rendre le code plus fiable et plus prévisible.
Il est en effet temps d'explorer comment effectuer des opérations avec nos variables, car jusqu'à présent,
nous n'avons pas appris grand-chose de pratique. Notre écran est resté complètement vide.

Commençons par apprendre comment afficher la valeur d'une variable.


Exactement, vous avez compris ! Pour afficher le contenu d'une variable, on utilise également "cout"
et les chevrons (<<), mais au lieu d'un texte, on place simplement le nom de la variable que l'on
souhaite afficher. C'est une manière importante de visualiser les données stockées dans nos
variables.
Code : C++
Une fois compilé, ce code affiche ceci à
cout << ageUtilisateur;
l'écran:
Prenons un exemple complet pour essayer.
Code : Console
#include <iostream> Code : C++
Votre age est : 16
using namespace std;
Exactement ce que l'on voulait
int main() ! On peut même faire encore
{ plus simple : tout mettre sur
une seule ligne ! Et on peut
int ageUtilisateur(16); même ajouter un retour à la
ligne à la fin.
cout << "Votre age est : ";
cout << ageUtilisateur;
Pensez à mettre un espace à la fin du
texte. Ainsi, la valeur de votre
return 0; variable sera détachée du texte lors
} de l'affichage.
Code : C++

#include <iostream> Il est également possible d'afficher simultanément le


contenu de plusieurs variables.
using namespace std;
int main()
{
int ageUtilisateur(16);
cout << "Votre age est :
" << ageUtilisateur <<
endl;
return 0;
}
Code : C++

#include <iostream>
#include <string>
using namespace std;
int main()
{
int qiUtilisateur(150);
string nomUtilisateur("Albert Einstein");
cout << "Vous vous appelez " << nomUtilisateur << " et votre QI
vaut " << qiUtilisateur << endl;
return 0;
} affiche le résultat escompté.
Ce qui
Code : Cons ole
Vous vous appelez Albert Einstein et votre QI vaut 150

Je suppose que vous n'aviez pas de doutes à ce sujet. Dans le prochain chapitre, nous aborderons
comment effectuer l'opération inverse : récupérer la saisie de l'utilisateur et la stocker dans une variable.
Les références
Avant de conclure ce chapitre, il est important d'aborder une notion cruciale : les références.
Comme je l'ai expliqué au début de ce chapitre, une variable peut être envisagée comme une case mémoire
avec une étiquette portant son nom. Dans la vie réelle, il est tout à fait possible d'apposer plusieurs
étiquettes sur un même objet. En C++, c'est similaire, on peut attribuer une deuxième (troisième, dixième,
etc.) étiquette à une même case mémoire. Ainsi, on dispose d'une deuxième manière d'accéder à la même
zone mémoire, comme si on donnait un surnom à une variable en plus de son nom habituel. On utilise
parfois le terme "alias", mais en C++, le mot correct est "référence".
En effet, on dispose d'une seule case mémoire, mais deux étiquettes qui lui sont associées. Pour
illustrer cela, on peut afficher l'âge de l'utilisateur de la manière habituelle et via une référence. On dit alors
que "maVariable" fait référence à "ageUtilisateur". Au niveau du code, on utilise une esperluette (&) pour
déclarer une référence sur une variable. Voyons cela avec un petit exemple concret.
int ageUtilisateur(16); //Déclaration d'une variable.
int& maVariable(ageUtilisateur); //Déclaration d'une référence
nommée maVariable qui est accrochée à la variable ageUtilisateur
à la ligne 1, vous déclarez une case mémoire nommée "ageUtilisateur" dans laquelle vous placez la valeur
16. Puis, à la ligne 3, vous attachez une deuxième étiquette (référence) à cette même case mémoire.
Désormais, vous avez deux moyens d'accéder au même espace dans la mémoire de votre ordinateur. C'est
une des caractéristiques puissantes et flexibles des références en C++.
Code : C++
#include <iostream> Il est crucial de noter que la référence
using namespace std; doit impérativement être du même type
int main() que la variable à laquelle elle est
{ attachée. Par exemple, un "int&" ne
int ageUtilisateur(18); //Une variable pour contenir l'âge de peut faire référence qu'à une variable de
l'utilisateur type "int", de même qu'un "string&"
int& maReference(ageUtilisateur); //Et une ne peut être associé qu'à une variable de
référence sur la variable 'ageUtilisateur' type "string". Le type de la référence
//On peut utiliser à partir d'ici doit correspondre au type de la variable
//'ageUtilisateur' ou 'maReference' indistinctement qu'elle référence.
//Puisque ce sont deux étiquettes de la même case en mémoire

cout << "Vous avez " << ageUtilisateur << " ans.
(via variable)"
<< endl;
//On affiche, de la manière habituelle

cout << "Vous avez " << maReference << " ans.
(via reference)"
<< endl;
//Et on affiche en utilisant la référence

return 0;
}
Après avoir été déclarée, vous pouvez manipuler une référence de la même manière que vous manipuleriez
la variable elle-même. Aucune distinction n'est faite entre les deux.

Euh… Mais à quoi es t-ce que cela peut bien servir ?

La question que vous posez est pertinente ! Dans l'exemple que vous avez donné, l'utilisation d'une
référence peut sembler superflue. Cependant, envisagez une situation où une variable est nécessaire dans deux
parties distinctes d'un programme, chacune étant développée par des programmeurs différents.
L'un pourrait être responsable de la déclaration de la variable, tandis que l'autre se chargerait
simplement de l'affichage. Dans ce cas, une référence devient utile pour permettre au deuxième programmeur
d'accéder à la variable. Je comprends que cela puisse sembler abstrait et sans utilité immédiate, mais il est
crucial de maîtriser cette notion, car elle sera fréquemment employée dans des cas plus complexes tout au long
de ce cours. Les références constituent un élément fondamental de C++ et méritent d'être comprises dès
maintenant.
En résumé
Une variable représente une donnée stockée en mémoire, et il existe différents types de variables en fonction de
la nature de l'information qu'elles contiennent à stocker : int, char, bool… Une variable doit être déclarée
avant utilisation. (int ageUtilisateur(16);)La valeur d'une variable peut être affichée à tout moment
avec cout. Les références sont des étiquettes qui permettent d'appeler une variable par un autre nom.
((int&maReference(ageUtilisateur);)
Une vraie calculatrice
Au chapitre précédent, nous avons abordé le concept des variables en présentant la mémoire d'une
calculatrice. Un ordinateur, en tant que super-calculatrice, ne se contente pas de stocker des données ; il est
également capable d'effectuer des calculs. J'espère que cette perspective vous intéresse, car c'est
précisément ce que je vais vous enseigner à faire.
Commençons en douceur avec la première opération que l'on effectue généralement sur une calculatrice,
vous voyez de quoi je parle, n'est-ce pas ? Exactement, il s'agit d'entrer des nombres pour les introduire dans
la machine. Ainsi, nous allons découvrir comment solliciter des informations auprès de l'utilisateur et
comment les enregistrer dans la mémoire. Pour cela, nous aurons besoin... de variables !

Dans un second temps, je vous expliquerai comment effectuer de simples calculs. Après avoir acquis cette
compétence, et puisque vous savez déjà comment afficher un résultat, vous pourrez mettre en pratique
l'ensemble de vos connaissances à travers un exercice pratique.
Demander des informations à l'utilisateur
Dans le chapitre précédent, j'ai expliqué comment afficher des variables dans la console. Maintenant, nous
allons aborder l'opération inverse : comment demander des informations à l'utilisateur et les stocker dans la
mémoire.
Lecture depuis la console
Comme vous l'avez certainement remarqué, le C++ emprunte de nombreux termes à l'anglais. C'est
particulièrement le cas pour le flux de sortie "cout", qui se prononce "c-out". Ce qui est pratique, c'est que
l'on peut immédiatement en déduire le nom du flux d'entrée, qui est "cin".
Avec "cout", les données sortent du programme, d'où l'utilisation du terme "out". Le contraire d'"out" en
anglais est "in", qui signifie "vers l'intérieur". C'est pourquoi on utilise "cin" pour faire entrer des
informations dans le programme. "cin" se décompose également sous la forme de "cin" et se prononce "si-
inne". Cette nuance est importante pour les discussions entre programmeurs. Mais ce n'est pas tout ! Si
"cout" est associé aux chevrons (<<) pour l'affichage, "cin" l'est également, mais dans l'autre sens (>>), pour
l'entrée de données.

Code : C++
#include <iostream> Que s 'es t-il passé exactement ? Code : Console
using namespace std;
Quel age avez-vous ?
int main() 23
{ Vous avez 23 ans !
cout << "Quel age avez-vous ?" << endl;

int ageUtilisateur(0); //On prepare une case mémoire pour


stocker un entier
cin >> ageUtilisateur; //On fait entrer un nombre dans cette case
cout << "Vous avez " << ageUtilisateur << " ans !" << endl;
//Et on l'affiche

return 0;
}
Le programme a tout d'abord affiché le texte "Quel âge avez-vous ?". Jusqu'à présent, rien de bien
compliqué. Ensuite, comme nous l'avons vu précédemment, à la ligne 8, le programme demande à l'ordinateur
de réserver une zone mémoire pour stocker un entier (int) et il la nomme "ageUtilisateur". C'est là
que cela devient vraiment intéressant. L'ordinateur affiche un curseur blanc clignotant et attend que l'utilisateur
saisisse quelque chose. Lorsque l'utilisateur a terminé et appuyé sur la touche Entrée de son clavier, le
programme prend ce qui a été saisi et le place dans la zone mémoire "ageUtilisateur", remplaçant ainsi
le 0 initial. En fin de compte, nous revenons à quelque chose de familier, car le programme affiche une petite
phrase et le contenu de la variable.
Une astuce pour les chevrons

Il est fréquent de se tromper dans le sens des chevrons. Vous ne seriez pas les premiers à écrire "cout >>" ou
"cin <<" de manière incorrecte. Pour vous rappeler la direction correcte, je vous conseille de considérer les
chevrons comme des flèches indiquant la direction dans laquelle les données se déplacent, soit depuis la
variable vers "cout" ou depuis "cin" vers votre variable. Pour une aide visuelle, un petit schéma peut être utile
(voir figure ci-dessous).
Lorsque vous affichez la valeur d'une variable, les données sortent du programme, ce qui est représenté par
une flèche allant de la variable vers "cout". En revanche, lorsque vous demandez une information à
l'utilisateur, c'est l'inverse : la valeur provient de "cin" et est dirigée vers la variable, illustré par une flèche
allant de "cin" vers la variable. C'est une manière pratique de se rappeler la direction correcte des chevrons
dans les opérations d'entrée et de sortie de données.
D'autres variables <<,

Évidemment, ce que je vous ai présenté marche aussi avec d'autres types de variables . Voyons cela avec un
petit exemple.
Code : C++
#include <iostream>
#include <string>
using namespace std;
int main()
{
cout << "Quel est votre prenom ?" << endl;
string nomUtilisateur("Sans nom"); //On crée une case mémoire pour contenirune chaine de caractères
cin >> nomUtilisateur; //On remplit cette case avec ce qu'écrit l'utilisateur
cout << "Combien vaut pi ?" << endl;
double piUtilisateur(-1.); //On crée une case mémoire pour stocker un nombre réel
cin >> piUtilisateur; //Et on remplit cette case avec ce qu'écritl'utilisateur
cout << "Vous vous appelez " << nomUtilisateur << " et vous pensez que pivaut " <<
piUtilisateur << "." << endl;
return 0;
}
Le problème des espaces

Avez-vous tes té le code précédent en mettant vos nom et prénom ? Regardons ce que cela
donne.
Code : Console
Quel est votre prenom ? Albert Einstein
Combien vaut pi ? Vous vous appelez Albert et vous pensez
que pi vaut 0.

L'ordinateur n'a rien demandé pour pi et le nom de famille a dis paru ! Que s 'es t-il pas s é ?

Le problème réside dans la gestion des espaces lors de la saisie. Lorsque l'utilisateur appuie sur Entrée,
l'ordinateur copie la saisie, mais il s'arrête au premier espace ou retour à la ligne. Cela peut causer des
problèmes avec les chaînes de caractères contenant des espaces. La solution est d'utiliser la fonction
"getline(cin, nomUtilisateur);" pour récupérer toute la ligne de saisie, évitant ainsi les coupures incorrectes.
#include <iostream>
#include <string>
using namespace std;
int main()
{
cout << "Quel est votre nom ?" << endl;
string nomUtilisateur("Sans nom"); //On crée une case mémoire
pour contenir une chaine de caractères
getline(cin, nomUtilisateur); //On remplit cette case avec toute la
ligne que l'utilisateur a écrit
cout << "Combien vaut pi ?" << endl;
double piUtilisateur(-1.); //On crée une case mémoire pour
stockerun nombre réel
cin >> piUtilisateur; //Et on remplit cette case avec ce
qu'écritl'utilisateur
cout << "Vous vous appelez " << nomUtilisateur << " et vous pensez que pivaut "
<< piUtilisateur << "." << endl;
return 0;
}
On retrouve les mêmes éléments qu'auparavant. Il y a cin et il y a le nom de la variable
(nomUtilisateur) sauf que, cette fois, ces deux éléments se retrouvent encadrés par des parenthèses
et séparés par une virgule au lieu des chevrons.
On retrouve les mêmes éléments qu'auparavant. Il y a cin et il y a le nom de la variable (nomUtilisateur) sauf
que, cettefois, ces deux éléments se retrouvent encadrés par des parenthèses et séparés par une virgule au lieu
des chevrons.
Cette fois le nom ne sera pas tronqué lors de la lecture et notre ami Albert pourra utiliser notre
programme sans soucis.
Code : Console
Quel est votre nom ?
Albert Einstein
Combien vaut pi ?
3.14
Vous vous appelez Albert Einstein et vous
pensez que pi vaut 3.14.

Si l'on utilise d'abord cin >> puis getline(), par exemple pour demander la valeur de pi avant de
demander le nom, le code ne fonctionne pas. L'ordinateur ne demande pas son nom à l'utilisateur et
affiche n'importe quoi. Pour pallier ce problème, il faut ajouter la ligne cin.ignore() après l'utilisation
des chevrons.
Code : C++
#include <iostream>
#include <string>
using namespace std;
int main()
{
cout << "Combien vaut pi ?" << endl;
double piUtilisateur(-1.); //On crée une case mémoire pour
stocker un nombre réel
cin >> piUtilisateur; //Et on remplit cette case avec ce
qu'écritl'utilisateur
cin.ignore();
cout << "Quel est votre nom ?" << endl;
string nomUtilisateur("Sans nom"); //On crée une case mémoire
pour contenir une chaine de caractères
getline(cin, nomUtilisateur); //On remplit cette case avec
toute la ligne que l'utilisateur a écrit
cout << "Vous vous appelez " << nomUtilisateur << " et vous
pensez que pivaut " << piUtilisateur << "." << endl;
return 0;
}
Avec cela, plus de souci. Quand on mélange l'utilisation des chevrons et de getline(), il faut toujours
placer l'instruction cin.ignore() après la ligne cin>>a. C'est une règle à apprendre. Voyons maintenant
ce que l'on peut faire avec des variables, par exemple additionner deux nombres.
Modifier des variables
Changer le contenu d'une variable

Je vous ai expliqué dans l'introduction de ce chapitre que la mémoire de l'ordinateur fonctionne de manière
similaire à celle d'une calculatrice, et que l'on peut effectuer des opérations de calcul sur un ordinateur en
utilisant des variables. Commençons par voir comment modifier le contenu d'une variable. On utilise le
symbole "=" pour effectuer un changement de valeur. Si vous avez une variable de type "int" et que vous
souhaitez modifier son contenu, vous écrivez le nom de la variable suivi du symbole "=" et enfin de la
nouvelle valeur. Cela s'appelle l'affectation d'une variable.

Code : C++
int unNombre(0); //Je crée une case mémoire nommée 'unNombre' et
qui contient le nombre 0
unNombre = 5; //Je mets 5 dans la case mémoire 'unNombre‘
On peut aussi directement affecter le contenu d'une variable à une autre
Code : C++
int a(4), b(5); //Déclaration de deux variables
a = b; //Affectation de la valeur de 'b' à 'a'.
Que se passe-t-il exactement ?
Lorsque l'ordinateur atteint la ligne 3 du code précédent, il lit le contenu de la case mémoire nommée "b", qui
contient un nombre. Ensuite, il ouvre la case mémoire nommée "a" et y écrit la valeur lue depuis "b",
remplaçant ainsi la valeur précédente qui s'y trouvait. Voici une illustration schématique de cette opération.

Code : C++
#include <iostream>
using namespace std;
int main()
{
int a(4), b(5); //Déclaration de deux variables
cout << "a vaut : " << a << " et b vaut : " << b << endl;
cout << "Affectation !" << endl;
a = b; //Affectation de la valeur de 'b' à 'a'.
cout << "a vaut : " << a << " et b vaut : " << b << endl;
return 0;
}
Avez-vous testé ? Non ? N'oubliez pas qu'il est important de tester les codes proposés pour bien comprendre.
Bon, comme je suis gentil, je vous donne le résultat.
Code : Console
a vaut : 4 et b vaut : 5
Affectation !
a vaut : 5 et b vaut : 5
Exactement ce que je vous avais prédit.
La valeur de "b" n'a pas changé ! Il est important de se rappeler que lors d'une affectation, seule la
variable à gauche du symbole "=" est modifiée. Cela ne signifie pas que les deux variables sont égales
! Seulement que le contenu de celle de droite est copié dans celle de gauche.

C'est un bon début, mais nous sommes encore loin d'une calculatrice. Il nous manque... les opérations !
Une vraie calculatrice de base !
Commençons par l'opération la plus simple : l'addition, bien sûr. Et je pense que je ne vais pas trop vous
surprendre en vous disant qu'on utilise le symbole "+".
Code : C++
int a(5), b(8), resultat(0);
resultat = a + b; //Et hop une addition pour la route!
Comme c'est votre première opération, je vais vous décrire précisément ce qui se passe. À la ligne 1, le
programme crée trois cases dans la mémoire, nommées a, b et resultat. Il remplit également ces cases avec
les valeurs 2, 3 et 0 respectivement. Tout cela, nous commençons à le connaître.
La ligne 3 modifie le contenu de la variable "resultat" en additionnant les valeurs de "a" et "b". L'ordinateur
effectue ce calcul en un instant.
Code : C++
#include <iostream>
using namespace std;
int main()
{
int resultat(0), a(5), b(8);
resultat = a + b;
cout << "5 + 8 = " << resultat << endl;
return 0;
}
Sur votre écran vous devriez voir :
Code : Console
5 + 8 = 13
En plus de l'addition, il existe quatre autres opérations courantes : la soustraction, la multiplication, la
division et le modulo. Voici un résumé de ces opérations dans un tableau récapitulatif :
Opération Symbole Exemple
Addition + resultat = a + b;
Soustaction - resultat = a - b;

Multiplication * resultat = a * b;

Division / resultat = a / b;

Modulo % resultat = a % b;

Mais qu'est-ce que le modulo ? Je n'ai pas vu cela à l'école.

Le modulo, également connu sous le nom de reste de la division entière, est le résultat de la division entière
où l'on obtient un quotient et un reste. Par exemple, lorsque l'on divise 10 par 3, on obtient un quotient de 3
(car 3 fois 3 est égal à 9), mais il reste un 1. Cet élément restant, dans ce cas 1, est ce que l'on appelle le
modulo.
L'opérateur modulo (%) permet de calculer ce reste de la division. Cela peut s'avérer utile dans divers
contextes de programmation.
Cet opérateur n'existe que pour les nombres entiers !

La division entre deux variables de type int renvoie la partie entière de la réponse, ce qui peut entraîner des
résultats tronqués, comme dans l'exemple de la division de 10 par 3, qui renvoie 3 au lieu de la valeur
exacte 3.333... Il est important de se rappeler de ce comportement lors de la division d'entiers.
En combinant les opérations de base et en utilisant plusieurs variables, il est possible de créer des
expressions mathématiques plus complexes, et les parenthèses peuvent être utilisées pour clarifier ces
expressions si nécessaire.
Code : C++
int a(2), b(4), c(5), d; //Quelques variables
d = ((a+b) * c ) - c; //Un calcul compliqué !
Toute expression valide en maths l'est aussi en C++.
Les constantes
Au lieu de modifier des variables, je vais maintenant vous expliquer comment déclarer des variables qui ne
peuvent pas être modifiées. En termes techniques, on les appelle des constantes. Ne vous inquiétez pas si
cela semble un peu technique, nous allons explorer cela plus en profondeur dans la suite du cours.

Euh, mais à quoi peuvent bien servir des variables non modifiables ?
En programmation, les constantes sont des valeurs qui ne changent pas pendant l'exécution du
programme. Elles sont particulièrement utiles pour stocker des valeurs fixes, comme le nombre de niveaux
dans un jeu, la valeur de Pi ou l'accélération due à la gravité sur Terre. Ces valeurs sont considérées comme
constantes car elles ne varient jamais pendant l'exécution du programme.

Les constantes sont déclarées de manière similaire aux variables, mais avec un mot-clé supplémentaire :
const. Voici comment déclarer une constante en C++ :
const int nombreNiveaux = 10;
const double pi = 3.14159265359;
const double accelerationDueAGravite = 9.81;

Dans ces exemples, nous avons déclaré trois constantes : nombreNiveaux, pi et


accelerationDueAGravite, avec leurs valeurs respectives. Une fois qu'une constante est définie, sa
valeur ne peut pas être modifiée ultérieurement dans le programme. Elles sont souvent écrites en lettres
majuscules pour les distinguer des variables normales, par exemple const double GRAVITE_TERRE =
9.81;.

Les constantes sont un moyen efficace de rendre votre code plus lisible et de donner du sens aux valeurs
fixes utilisées dans votre programme.
Déclarer une constante
On déclare une variable normale et on ajoute le mot-clé const entre le type et le nom.
Code : C++
int const nombreNiveaux(10);
Cela marche bien sûr avec tous les types de variables.
Code : C++
string const motDePasse(« Azerty123"); //Le mot de passe secret
double const pi(3.14);
unsigned int const pointsDeVieMaximum(100); //Le nombre maximal de
points de vie

L'utilisation de const en programmation est recommandée pour déclarer des constantes. Cela améliore la
lisibilité du code, réduit les erreurs potentielles, permet des optimisations de compilation et facilite la
maintenance du code. C'est particulièrement utile pour définir des valeurs immuables pendant l'exécution
du programme.
Nous discuterons plus en détail des constantes dans les prochains chapitres. Pour l'instant, préparez-
vous pour votre premier exercice.
Un premier exercice
Nous disposons désormais des compétences requises pour élaborer votre premier programme concret.
Dans l'exemple précédent, le programme réalisait l'addition de deux nombres préalablement définis. Il
serait nettement plus captivant de permettre à l'utilisateur d'entrer ces deux nombres à additionner. Voici
donc votre premier exercice : demandez à l'utilisateur de fournir deux nombres, effectuez leur addition,
puis affichez le résultat.

De quoi avons-nous besoin ici ?

Afin de résoudre le premier exercice, nous devons créer des variables pour stocker les deux nombres
que l'utilisateur va entrer. Pour effectuer des calculs dans le programme, il est essentiel de sélectionner le
type de données adéquat pour ces variables, comme int, unsigned int ou double. Dans ce cas
précis, l'utilisation du type double est conseillée pour prendre en charge les nombres à virgule.
#include <iostream>
using namespace std;
int main()
{
double a(0), b(0); //Déclaration des variables utiles
//…
return 0;
}
L'étape suivante consiste à solliciter les nombres à l'utilisateur. Je suis sûr que vous vous souvenez que cela
se fait en utilisant cin >>. Nous pouvons donc aller de l'avant et écrire :
Code : C++
#include <iostream>
using namespace std;
int main()
{
double a(0), b(0); //Déclaration des variables utiles
cout << "Bienvenue dans le programme d'addition a+b !" << endl;
cout << "Donnez une valeur pour a : "; //On demande le premier
nombre
cin >> a;
cout << "Donnez une valeur pour b : "; //On demande le deuxième
nombre
cin >> b;
//…
return 0;
}
Pour réaliser l'addition et afficher le résultat du calcul, il est nécessaire de créer une variable constante
nommée "resultat". Cette variable sera initialisée avec le résultat du calcul en utilisant l'opérateur "+".
Code : C++
#include <iostream>
using namespace std;
int main()
{
double a(0), b(0); //Déclaration des variables utiles
cout << "Bienvenue dans le programme d'addition a+b !" << endl;
cout << "Donnez une valeur pour a : "; //On demande le premier
nombre
cin >> a;
cout << "Donnez une valeur pour b : "; //On demande le deuxième
nombre
cin >> b;
double const resultat(a + b); //On effectue l'opération
cout << a << " + " << b << " = " << resultat << endl;
//On affiche le résultat
return 0;
}
Code : Console
Bienvenue dans le programme d'addition a+b !
Donnez une valeur pour a : 123.784
Donnez une valeur pour b : 51.765
123.784 + 51.765 = 175.549

Désormais, l'objectif est de calculer le produit de a et b au lieu de leur somme, ce qui implique une
opération plus complexe : demander à l'utilisateur deux nombres entiers et calculer à la fois le quotient et
le reste de leur division.
Les raccourcis

Après avoir accompli cet exercice, vous avez désormais acquis une maîtrise des opérations de base. Il peut
être surprenant de constater qu'il n'y a pas d'autres opérations fondamentales à apprendre ! Ces cinq
opérations constituent le socle de toutes les manipulations arithmétiques, y compris celles nécessaires à la
création de jeux vidéo, comme nous l'avons évoqué dans le chapitre d'introduction. Cependant, il existe
quelques variantes intéressantes que je suis sûr que vous apprécierez.

L'incrémentation

L'une des opérations informatiques les plus courantes est l'incrémentation, qui consiste à ajouter "1" à une
variable. Cette opération est fréquemment utilisée pour des actions telles que passer d'un niveau à un autre
dans un jeu, augmenter le nombre de points de vie d'un personnage, ajouter un joueur à une partie, etc. Vous
possédez déjà les connaissances nécessaires pour effectuer une incrémentation de variable.
Code : C++
int nombreJoueur(4); //Il y a 4 joueurs dans la partie
nombreJoueur = nombreJoueur + 1; //On en ajoute un
//À partir d'ici, il y a 5 joueurs
Très bien ! Cependant, les informaticiens sont connus pour leur fainéantise, et la deuxième ligne de ce code est
un peu trop longue à écrire. Les créateurs du C++ ont donc introduit une notation spéciale pour ajouter 1 à une
variable. Voici comment cela fonctionne.
Code : C++
int nombreJoueur(4); //Il y a 4 joueurs dans la partie
++nombreJoueur;
//À partir d'ici, il y a 5 joueurs
On utilise le symbole "++". On écrit "++" suivi du nom de la variable et on termine par le point-virgule
habituel. Ce code a exactement le même effet que le précédent, mais il est plus succinct à écrire.
Il est également possible d'écrire "nombreJoueur++", c'est-à-dire de placer l'opérateur "++" après le
nom de la variable. Cette action est appelée la post-incrémentation, à l'opposé de la pré-incrémentation qui
consiste à placer "++" avant le nom de la variable.
Vous pourriez considérer cela comme une petite astuce, mais je suis sûr que vous apprécierez
rapidement ce genre de raccourcis !

En effet, cette astuce est si courante qu'elle est intégrée dans le nom du langage ! Oui, oui, "C++" peut
être interprété comme "C incrémenté" ou, de manière plus précise, "C amélioré". Les informaticiens
ont un sens de l'humour bien particulier !
La décrémentation
La décrémentation est l'opération inverse, consistant à soustraire 1 à une variable. Voici la version sans
raccourci de cette opération :
Code : C++
int nombreJoueur(4); //Il y a 4 joueurs dans la partie
nombreJoueur = nombreJoueur - 1; //On en enlève un
//À partir d'ici, il y a 3 joueurs
Je suis presque sûr que vous connaissez déjà la version courte. On utilise ++ pour ajouter 1, donc -- pour
soustraire 1.
Code : C++
Simple, non ?
int nombreJoueur(4); //Il y a 4 joueurs dans la partie
--nombreJoueur; //On en enlève un
//À partir d'ici, il y a 3 joueurs
Les autres opérations
Bien sûr, ajouter ou soustraire 1 est utile, mais pour des opérations plus complexes, il existe également des
raccourcis. Par exemple, si l'on souhaite diviser une variable par 3, en version longue, on écrirait :
Code : C++
double nombre(456);
nombre = nombre / 3;
//À partir d'ici, nombre vaut 456/3 = 152
La version courte utilise le symbole /= pour obtenir exactement le même résultat.
Code : C++
double nombre(456);
nombre /= 3;
//À partir d'ici, nombre vaut 456/3 = 152
Il existe des raccourcis pour toutes les opérations de base, à savoir + =, - =, * =, /= et %=, qui permettent
d'ajouter, soustraire, multiplier, diviser et obtenir le reste de la division. Ces raccourcis sont pratiques et
couramment utilisés en programmation. Je vais vous donner un exemple pour illustrer leur utilisation
:Code : C++
#include <iostream>
using namespace std;
int main()
{
double nombre(5.3);
nombre += 4.2; //'nombre' vaut maintenant 9.5
nombre *= 2.; //'nombre' vaut maintenant 19
nombre -= 1.; //'nombre' vaut maintenant 18
nombre /= 3.; //'nombre' vaut maintenant 6
return 0;
}
Ces opérations sont utiles quand il faut ajouter ou soustraire autre chose que 1.
Encore plus de maths !
Vous en voulez encore ? Ah je vois, vous n'êtes pas satisfaits de votre calculatrice. C'est vrai qu'elle est
encore un peelle ne connaît que les opérations de base. Pas vraiment génial pour la super-super-calculatrice
qu'est votre ordinateur
Ne partez pas ! J'ai mieux à vous proposer.
L'en-tête cmath
Pour avoir accès à plus de fonctions mathématiques, il suffit d'ajouter une ligne en tête de votre programme,
comme désire utiliser des variables de type string. La directive à insérer est :
Code : C++
#include <cmath>
Jusque là, c'est très simple. Et dans cmath il y a « math », ce qui devrait vous réjouir. On est sur la bonne voie.

Je vais vous présenter comment utiliser quelques fonctions mathématiques en C++. Il se peut très bien que vous ne
sachiez pas ce que sont ces fonctions : ce n'est pas grave, elles ne vous seront pas utiles dans la suite du cours. Vous
saurez ce qu'elles représentent quand vous aurez fait un peu plus de maths.

Commençons avec une fonction utilisée très souvent, la racine carrée. En anglais, racine carrée se dit
square root et, en abrégé,on écrit parfois sqrt. Comme le C++ utilise l'anglais, c'est ce mot là qu'il va falloir
retenir et utiliser.
Pour utiliser une fonction mathématique, on écrit le nom de la fonction suivi, entre parenthèses, de la valeur
à calculer. On utilise alors l'affectation pour stocker le résultat dans une variable.
Code : C++
resultat = fonction(valeur);
C'est comme en math quand on écrit . Il faut juste se souvenir du nom compliqué des fonctions. Pour la
racine carrée, cela donnerait resultat = sqrt(valeur);.

N'oubliez pas le point-virgule à la fin de la ligne !


Prenons un exemple complet, je pense que vous allez comprendre rapidement le principe.

Code : C++
#include <iostream>
#include <cmath> //Ne pas oublier cette ligne
using namespace std;
int main()
{ double const nombre(16); //Le nombre dont on veut la racine
//Comme sa valeur ne changera pas on
met 'const'
double resultat; //Une case mémoire pour stocker le Résultat
resultat = sqrt(nombre); //On effectue le calcul !
cout << "La racine de " << nombre << " est " << resultat <<
endl;
return 0;}
Voyons ce que cela donne.
Code : Console
La racine de 16 est 4
Votre ordinateur calcule correctement. Mais je ne pense pas que vous en doutiez.
Voyons s 'il y a d'autres fonctions à disposition.
Quelques autres fonctions présentes dans cmath
Comme il y a beaucoup de fonctions, je vous propose de tout ranger dans un tableau.

Les fonctions trigonométriques (sin(), cos(),… ) utilisent les radians comme unité d'angles

Il existe encore beaucoup d'autres fonctions ! Je ne vous ai mis que les principales pour ne pas qu'on
se perde.

On parle de mathématiques, ces fonctions ne sont donc utilisables qu'avec des variables qui représentent des
nombres (double, int et unsigned int). Prendre la racine carrée d'une lettre ou calculer le cosinus
d'une phrase n'a de toute façon pas de sens.
Nom de la fonction Symbole Fonction Mini-exemple

Racine carrée sqrt() resultat = sqrt(valeur);

Sinus sin() resultat = sin(valeur);

Cosinus cos() resultat = cos(valeur);

Tangente tan() resultat = tan(valeur);

Exponentielle exp() resultat = exp(valeur);

Logarithme népérien log() resultat = log(valeur);

Logarithme en base 10 log10() resultat = log10(valeur);

Valeur absolue fabs() resultat = fabs(valeur);

Arrondi vers le bas floor() resultat = floor(valeur);

Arrondi vers le haut ceil() resultat = ceil(valeur);


Le cas de la fonction puissance
Comme toujours, il y a un cas particulier : la fonction puissance. Comment calculer ? Il faut utiliser la
fonction pow() qui est un peu spéciale. Elle prend deux arguments, c'est-à-dire qu'il faut lui donner deux
valeurs entre les parenthèses. Comme pour la fonction getline() dont je vous ai parlé avant.
Si je veux calculer , je vais devoir procéder ainsi :
Code : C++
double const a(4);
double const b(5);
double const resultat = pow(a,b);
Je déclare une variable (constante) pour mettre le , une autre pour stocker le et finalement une dernière
pour le résultat. Rien nouveau jusque là. J'utilise la fonction pow() pour effectuer le calcul et j'utilise le
symbole = pour initialiser la variable resultat avec la valeur calculée par la fonction.
Nous pouvons donc reprendre l'exercice précédent et remplacer l'addition par notre nouvelle amie, la
fonction puissance. Je vous laisse essayer.
Voici ma version:

Code : C++
#include <iostream>
#include <cmath> //Ne pas oublier !
using namespace std;
int main()
{
double a(0), b(0); //Déclaration des variables utiles
cout << "Bienvenue dans le programme de calcul de a^b !" << endl;
cout << "Donnez une valeur pour a : "; //On demande le premier
nombre
cin >> a;
cout << "Donnez une valeur pour b : "; //On demande le deuxième
nombre
cin >> b;
double const resultat(pow(a, b)); //On effectue l'opération
//On peut aussi écrire comme avant :
//double const resultat = pow(a,b);
//Souvenez-vous des deux formes possibles
//De l'initialisation d'une variable
cout << a << " ^ " << b << " = " << resultat << endl;
//On affiche le résultat
return 0;
}
Code : Console
Bienvenue dans le programme de calcul de a^b !
Donnez une valeur pour a : 4
Donnez une valeur pour b : 5
4 ^ 5 = 1024

En résumé

Pour demander à l'utilisateur de saisir une information au clavier, on utilise cin >> variable;. La
valeur saisie sera stockée dans la variable. Il ne faut pas confondre le sens des chevrons cout << et cin
>>. On peut faire toutes sortes d'opérations mathématiques de base en C++ : addition, soustraction,
multiplication… Exemple : resultat = a + b;
Les constantes sont des variables qu'on ne peut pas modifier une fois qu'elles ont été créées. On utilise le
mot const pour les définir. Pour ajouter 1 à la valeur d'une variable, on effectue ce qu'on appelle une
incrémentation : variable++;. L'opération inverse, appelée décrémentation, existe aussi. Si vous
souhaitez utiliser des fonctions mathématiques plus complexes, comme la racine carrée, il faut inclure l'en-
tête <cmath> dans votre code et faire appel à la fonction comme dans cet exemple : resultat =
sqrt(100);
Les structures de contrôle
Les programmes doivent être en mesure de prendre des décisions, et pour ce faire, les développeurs utilisent
ce qu'on appelle des structures de contrôle. Ce terme un peu technique englobe en réalité deux concepts que
nous explorerons dans ce chapitre :
1. Les conditions : Elles permettent d'insérer dans le programme des règles du type "Si ceci se produit, alors
fais cela."
2. Les boucles : Elles permettent de répéter un ensemble d'instructions plusieurs fois.
3. La maîtrise des structures de contrôle est fondamentale ! Bien que ce chapitre puisse sembler abordable, il
est essentiel de bien comprendre ces concepts de base. Ils vous serviront tout au long de votre carrière de
développeur en C++, et même dans d'autres langages, car les principes sont similaires.

Les conditions
Afin de permettre à un programme de prendre des décisions, il recourt à des instructions conditionnelles dans
son code source, couramment désignées sous le terme de 'structures conditionnelles'. Le concept est assez
simple : il s'agit de faire en sorte que le programme réagisse de manière variée en fonction des circonstances.
Dans cette section, nous allons explorer la manière d'employer ces conditions fondamentales dans nos
programmes en langage C++.
Les conditions en programmation permettent d'évaluer des variables en fonction de critères tels que leur valeur.
Ces variables sont celles que nous avons étudiées dans le chapitre précédent et qui sont stockées en mémoire.
Pour illustrer, on peut se demander si une variable est supérieure à 10 ou si elle contient un mot de passe
secret. Pour effectuer ces évaluations, on utilise des symboles spécifiques, que voici :
SYMBOLE SIGNIFICATION

== Est égal à

> Est supérieur à

< Est inférieur à

>= Est supérieur ou égal à

<= Est inférieur ou égal à

!= Est différent de
Faites très attention : en C++, il y a bien 2 symboles « = » pour tester l'égalité. Les débutants oublient souvent cela et
n'écrivent qu'un seul « = », ce qui n'a pas la même signification.

Nous allons utiliser ces symboles pour effectuer des comparaisons dans nos conditions.
Il faut savoir qu'il existe en C++ plusieurs types de conditions pour faire des tests, mais la plus importante,
qu'il faut impérativement connaître, est sans aucun doute la condition if.
La condition if
Comme je vous l'ai expliqué, les conditions permettent de tester des variables. Je vous propose donc de
créer un petit programme en même temps que moi et de réaliser des tests pour vérifier que vous avez bien
compris le principe. Commençons avec le code suivant :
Code : C++
#include <iostream>
using namespace std;
int main()
{
int nbEnfants(2);
int nbEnfants(2);
return 0;
}
Ce code actuel n'exécute aucune action pour le moment. Il commence par déclarer une variable nbEnfants (qui
représente un nombre d'enfants), puis il se termine sans effectuer aucune opération.
Une première condition if
Supposons que nous souhaitons afficher un message de félicitations lorsque quelqu'un a des enfants. Pour
cela, nous allons introduire une condition qui vérifie si le nombre d'enfants est supérieur à 0, et si c'est le cas,
affiche un message approprié.
Code : C++
#include <iostream>
using namespace std;
int main()
{
int nbEnfants(2);
if (nbEnfants > 0)
{
cout << "Vous avez des enfants, bravo !" << endl;
}
cout << "Fin du programme" << endl;
return 0;
}
Ce code affiche :
Code : Console
Vous avez des enfants, bravo !
Fin du programme
Regardez bien la ligne suivante :
if (nbEnfants > 0)
La condition effectue le test suivant : "Si le nombre d'enfants est supérieur à 0" (en anglais, "if" signifie "si").
Si ce test est validé (c'est-à-dire si la personne a effectivement des enfants), alors l'ordinateur exécute les
lignes de code situées entre les accolades, ce qui entraîne l'affichage du message "Vous avez des enfants,
bravo !«
Et si la personne n'a pas d'enfants, qu'est-ce qui se passe ?

En cas de résultat négatif du test, l'ordinateur n'exécute pas les instructions situées entre les accolades. Il
passe plutôt à la ligne suivante après la fermeture des accolades. Dans notre exemple, si la personne n'a
pas d'enfants, seul le message suivant sera affiché :
Code : Console
Fin du programme

Faites le test ! Changez la valeur de la variable nbEnfants, passez-la à 0 et regardez ce qui se produit.
else : ce qu'il faut faire si la condition n'est pas vérifiée
Bien sûr, si vous souhaitez que votre programme accomplisse une action spécifique lorsque la condition
n'est pas satisfaite, vous pouvez utiliser le mot-clé "else", qui signifie "sinon". Par exemple, vous pouvez
afficher un autre message si la personne n'a pas d'enfant.:
Code : C++
#include <iostream>
using namespace std;
int main()
{
int nbEnfants(0);
if (nbEnfants > 0)
{
cout << "Vous avez des enfants, bravo !" << endl;
}
else
{
cout << "Eh bien alors, vous n'avez pas d'enfant ?" << endl;
}
cout << "Fin du programme" << endl;
return 0;
}
Ce code affiche :
Code : Console
Eh bien alors, vous n'avez pas d'enfant ?
Fin du programme ... car j'ai modifié la valeur de la variable nbEnfants au début, assurez-vous de bien regarder.
Si vous attribuez une valeur supérieure à 0, le message redeviendra celui que nous avons vu précédemment !
Le fonctionnement est en réalité assez simple : l'ordinateur commence par évaluer la condition du "if" et constate que la
condition est fausse, c'est-à-dire que la personne n'a pas au moins 1 enfant.
L'ordinateur "saute" donc l'ensemble des instructions situées entre les premières accolades du "if" et arrive à la ligne "else",
qui signifie "sinon". Il exécute ensuite les actions spécifiées après "else" (comme illustré dans la figure suivante).
else if : effectuer un autre test
Il est possible d'effectuer plusieurs tests consécutifs. Imaginons que nous souhaitons réaliser le test suivant :

• Si le nombre d'enfants est égal à 0, afficher ce message "Message 1".


• Sinon, si le nombre d'enfants est égal à 1, afficher ce message "Message 2".
• Sinon, si le nombre d'enfants est égal à 2, afficher ce message "Message 3".
• Sinon, afficher ce message "Message 4".
Pour effectuer ces tests successifs dans l'ordre, nous utilisons la condition "else if", qui signifie "sinon si".
Les tests sont lus séquentiellement jusqu'à ce que l'un d'entre eux soit vérifié.
Code : C++
#include <iostream>
using namespace std;
int main()
{
int nbEnfants(2);
if (nbEnfants == 0)
{
cout << "Eh bien alors, vous n'avez pas d'enfant ?" << endl;
}
else if (nbEnfants == 1)
{
cout << "Alors, c'est pour quand le deuxieme ?" << endl;
}
else if (nbEnfants == 2)
{
cout << "Quels beaux enfants vous avez la !" << endl;
}
else
{
cout << "Bon, il faut arreter de faire des gosses maintenant
!" << endl;
}
cout << "Fin du programme" << endl;
return 0;
}
Dans notre cas, avec 2 enfants :

• L'ordinateur commence par tester si nous n'avons pas d'enfant (0).


• Comme ce n'est pas le cas, il passe au premier "else if" : avons-nous 1 enfant ? Non.
• L'ordinateur teste donc le deuxième "else if" : avons-nous 2 enfants ? Oui ! Donc il affiche le message
"Quels beaux enfants vous avez !" Si aucune des conditions n'avait été vérifiée, c'est le message du "else"
qui aurait été affiché : "Bon, il faut arrêter de faire des enfants maintenant !"
La condition switch

En théorie, la condition "if" permet de réaliser autant de tests que nécessaire. Cependant, en pratique, il existe
d'autres méthodes pour effectuer des tests. Par exemple, la condition "switch" simplifie l'écriture de conditions
qui testent plusieurs valeurs possibles pour une même variable.

Prenons l'exemple du test que nous avons effectué sur le nombre d'enfants :

• A-t-il 0 enfant ?
• A-t-il 1 enfant ?
• A-t-il 2 enfants ?
...
Il est possible de réaliser ce type de tests avec des "if... else if... else...", mais une condition "switch" a tendance
à rendre le code plus lisible dans ce genre de situations. Voici à quoi ressemblerait le code précédent avec
"switch" :
Code : C++
#include <iostream>
using namespace std;
int main()
{
int nbEnfants(2);
switch (nbEnfants)
{
case 0:
cout << "Eh bien alors, vous n'avez pas d'enfant ?" <<
endl;
break;
case 1:
cout << "Alors, c'est pour quand le deuxieme ?" << endl;
break;
case 2:
cout << "Quels beaux enfants vous avez la !" << endl;
break;
default:
cout << "Bon, il faut arreter de faire des gosses
maintenant !" << endl;
break;
}
return 0;
}
Ce qui affiche, Code : Console
Quels beaux enfants vous avez la !
Ce code présente une structure particulière. Il commence par indiquer la variable à évaluer, "nbEnfants" à la
ligne 9, puis il examine différents cas possibles en fonction de la valeur de cette variable, tels que 0, 1, 2, etc.
L'utilisation de "break" est nécessaire pour arrêter les évaluations dès qu'une condition est remplie. Enfin,
l'instruction "default" à la fin est exécutée si aucun des tests précédents n'est vérifié, équivalant au
"sinon" dans une structure conditionnelle classique.
switch ne permet de tester que l'égalité. Vous ne pouvez pas tester « Si le nombre d'enfants est
supérieur à 2 » avec switch : il faut dans ce cas utiliser if.
De plus, switch ne peut travailler qu'avec des nombres entiers (int, unsigned int, char). Il est
impossible de tester des nombres décimaux (double). switch est donc limité en termes de possibilités
mais cette instruction propose une écriture alternative parfois plus pratique dans des cas simples.

Booléens et combinaisons de conditions


Allons un peu plus loin avec les conditions. Nous allons découvrir deux notions plus avancées et néanmoins
essentielles : les booléens et les combinaisons de conditions.
Les booléens
Vous vous souvenez du type bool ? Ce type de données peut stocker deux valeurs :
1. true (vrai) ;
2. false (faux).
Ce type est souvent utilisé avec les conditions. Quand on y pense, c'est logique : une condition est soit vraie,
soit fausse. Une variable booléenne aussi.
Si je vous parle du type bool, c'est parce qu'on peut l'utiliser d'une façon un peu particulière dans les
conditions. Pour commencer, regardez ce code :
Code : C++
bool adulte(true);
if (adulte == true)
{
cout << "Vous etes un adulte !" << endl;
}
Cette condition vérifie la valeur de la variable "adulte" et affiche un message si elle est vraie (true).

Vous vous demandez peut-être où je veux en venir ? En réalité, il est possible d'omettre la partie« == true »
dans la condition, cela revient au même ! Regardez ce code, qui est équivalent :
Code : C++
bool adulte(true);
if (adulte)
{
cout << "Vous etes un adulte !" << endl;
}
L'ordinateur comprend que vous voulez vérifier si la variable booléenne vaut true. Il n'est pas nécessaire de
rajouter « ==true ».

Est-ce que cela ne rend pas le code plus difficile à lire ?

Le code est plus court et plus lisible ! "if (adulte)" se traduit simplement par "S'il est adulte".

Je vous encourage à utiliser cette notation abrégée lorsque vous testez des variables booléennes. Elle
contribue à clarifier votre code et à rendre certaines conditions plus compréhensibles.

En ce qui concerne la combinaison de conditions, pour des conditions plus complexes, vous pouvez
effectuer plusieurs tests au sein d'un même "if". Pour ce faire, vous devrez utiliser de nouveaux opérateurs
&& ET
|| OU
! NON
Test ET
! NON
Imaginons : on veut tester si la personne est adulte et si elle a au moins 1 enfant. On va donc écrire :
Code : C++
if (adulte && nbEnfants >= 1)
Les deux symboles && signifient « ET ». Notre condition se dirait en français : « Si la personne est adulte ET si
le nombre d'enfants est supérieur ou égal à 1 ».

Notez que j'aurais également pu écrire cette condition ainsi : if (adulte == true &&
nbEnfants >= 1). Cependant, comme je vous l'ai expliqué un peu plus tôt, il est facultatif de préciser
« == true » sur les booléens et c'est une habitude que je vous invite à prendre.

Test OU
Les structures de contrôle, telles que les conditions et les boucles, sont essentielles en programmation. Les
conditions permettent de faire des tests sur des variables, en utilisant des opérateurs tels que "if". On peut
également utiliser "else if" pour des tests successifs. L'opérateur "switch" simplifie les tests de plusieurs
valeurs possibles pour une variable. Pour les variables booléennes, il est possible d'omettre "== true". Pour
combiner des conditions, on utilise "||" pour le OU.
Code : C++:
if (nbEnfants == 1 || nbEnfants == 2)
Test NON
Il est maintenant temps de vous présenter un dernier symbole : le point d'exclamation "!". En informatique, le
point d'exclamation signifie "Non". Vous devez placer ce signe devant votre condition pour exprimer "Si cela
n'est pas vrai". Voici comment cela s'exprime en code C++ :
if (!adulte);Effectivement, l'utilisation du point d'exclamation "!" peut se traduire par "Si la personne
n'est pas adulte". C'est un moyen courant d'exprimer des conditions négatives en programmation.
Les boucles
Les boucles sont utilisées pour répéter un ensemble d'instructions plusieurs fois dans un programme. Le
concept est illustré dans la figure suivante.

1. L'ordinateur lit les instructions de haut en bas, comme d'habitude.


2. Une fois qu'il atteint la fin de la boucle, il retourne à la première instruction.
3. Il reprend alors la lecture des instructions de haut en bas.
4. Ce processus se répète tant que la condition spécifiée est vraie. Par exemple, vous pouvez créer une
boucle qui dit : "Tant que l'utilisateur donne un nombre d'enfants inférieur à 0, redemander le nombre
d'enfants."
5. Il existe trois types de boucles à connaître :
while ;
do ... while ;
for.
La boucle while  Cette boucle s 'utilise comme ceci :
Code : C++
while (condition)
{
/* Instructions à répéter */
}

Tout ce qui se trouve entre les accolades sera répété tant que la condition est vérifiée. Essayons de mettre
en pratique ce que j'ai mentionné précédemment : nous allons redemander à l'utilisateur le nombre d'enfants
tant que celui-ci est inférieur à 0. Ce type de boucle permet de garantir que l'utilisateur entre un nombre
valide.
Code : C++
int main()
{
int nbEnfants(-1); // Nombre négatif pour pouvoir entrer dans la
boucle
while (nbEnfants < 0)
{
cout << "Combien d'enfants avez-vous ?" << endl;
cin >> nbEnfants;
}
cout << "Merci d'avoir indiquer un nombre d'enfants correct. Vous
en avez " << nbEnfants << endl;
return 0;
}
Voici un exemple d'utilisation de ce programme :
Code : Console
Combien d'enfants avez-vous ?
-3
Combien d'enfants avez-vous ?
-5
Combien d'enfants avez-vous ?
2
Merci d'avoir indique un nombre d'enfants correct. Vous en avez 2
Tant que vous saisissez un nombre négatif, la boucle recommence. En effet, elle teste while
(nbEnfants < 0), c'est-àdire «Tant que le nombre d'enfants est inférieur à 0 ». Dès que le Nombre
devient supérieur ou égal à 0, la boucle s'arrête et le programme continue après l'accolade fermante.

Vous noterez que j'ai initialisé la variable nbEnfants à -1. En effet, pour que l'ordinateur veuille bien entrer
une première fois dans la boucle, il faut faire en sorte que la condition soit vraie la première fois.

La boucle do ... while


Cette boucle est très similaire à la précédente, à la différence près que la condition n'est évaluée qu'à la fin.
Cela signifie que le contenu de la boucle sera toujours exécuté au moins une fois. Cette boucle a la forme
suivante :
Code : C++
do
{
/* Instructions */
} while (condition);
Notez bien la présence du point-virgule tout à la fin !
Reprenons le code précédent et utilisons cette fois un do ... while :
Code : C++
int main()
{
int nbEnfants(0);
do
{
cout << "Combien d'enfants avez-vous ?" << endl;
cin >> nbEnfants;
} while (nbEnfants < 0);
cout << "Merci d'avoir indique un nombre d'enfants correct. Vous
en avez " << nbEnfants << endl;
return 0;
}
Le principe est le même, le programme se comporte de la même manière. L'avantage principal de la boucle
"do ... while" est qu'elle garantit que la boucle sera exécutée au moins une fois. De plus, dans ce cas, il
n'est pas nécessaire d'initialiser "nbEnfants" à -1, car le nombre d'enfants est déjà initialisé à 0 (comme
on a l'habitude de le faire). Comme la condition n'est évaluée qu'après le premier passage de la boucle, les
instructions sont toujours lues au moins une fois.
La boucle for
Ce type de boucle, que l'on rencontre fréquemment, permet de regrouper les étapes d'initialisation, de
condition et d'incrémentation en une seule structure. Voici sa forme :
Code : C++
for (initialisation ; condition ; incrementation)
{
}
Regardons un exemple concret qui affiche des nombres de 0 à 9 :
Code : C++
int main()
{
int compteur(0);
for (compteur = 0 ; compteur < 10 ; compteur++)
{
cout << compteur << endl;
}
return 0;
}
Ce code affiche :
0
1
2
3
4
5
6
7
8
9
Code : Console
Effectivement, sur la ligne "for", les trois instructions que vous avez mentionnées sont présentes :
• Une initialisation (compteur = 0) : La variable "compteur" est définie à 0 au début de la boucle. Il est à noter
que cela avait déjà été fait à la ligne précédente, ce qui n'était pas vraiment nécessaire ici.
• Une condition (compteur < 10) : Nous vérifions que la variable "compteur" est inférieure à 10 à chaque
nouveau tour de boucle.
• Une incrémentation (compteur++) : À chaque tour de boucle, nous ajoutons 1 à la variable "compteur". C'est
pourquoi nous voyons s'afficher à l'écran des nombres de 0 à 9.
Dans la dernière section du "for", vous avez la possibilité de modifier la variable de différentes manières.
Vous pouvez effectuer une décrémentation (compteur--), avancer de 2 en 2 (compteur += 2), ou utiliser
d'autres opérations pour ajuster la variable selon vos besoins. Cela vous permet de contrôler finement la
manière dont la variable évolue à chaque itération de la boucle.
Notez qu'il est courant d'initialiser la variable directement à l'intérieur du for, comme ceci :
Code : C++
int main()
{
for (int compteur(0) ; compteur < 10 ; compteur++)
{
cout << compteur << endl;
}
return 0;
}
a portée de la variable est limitée à la durée de la boucle "for". C'est la forme la plus courante de cette boucle.
On ne déclare généralement la variable avant le "for" que si elle est nécessaire en dehors de la boucle, bien que
cela soit un cas assez rare. En général, vous déclarez et utilisez la variable directement dans la boucle "for"
pour limiter sa portée au contexte de la boucle.

Quand utiliser un for et quand utiliser un while ?


On utilise la boucle for quand on connaît le nombre de répétitions de la boucle et on utilise le plus souvent la
boucle while quand on ne sait pas combien de fois la boucle va être effectuée.
En résumé
• Les conditions sont utilisées pour évaluer la valeur des variables et ajuster le comportement du programme
en conséquence. La condition la plus courante est le "if" (si), suivi de "else if" (sinon si) et "else"
(sinon).
• La condition "switch" est plus spécifique et permet de tester les différentes valeurs possibles d'une seule
variable.
• Les boucles sont utilisées pour répéter un ensemble d'instructions plusieurs fois. Il existe trois types de
boucles : "while", "do... while" et "for".
• La boucle "for" est généralement utilisée lorsque le nombre d'itérations est connu à l'avance.
• Les boucles "while" et "do... while" sont utilisées lorsque vous souhaitez répéter des instructions
jusqu'à ce qu'une condition spécifique soit remplie.
Découper son programme en fonctions

Dans ce chapitre, nous avons exploré l'utilisation des boucles et des structures conditionnelles pour
influencer le flux d'un programme. Avant cela, nous avons introduit les variables, un concept fondamental en
programmation. Maintenant, passons aux fonctions, des éléments essentiels dans tous les programmes C++.
Les fonctions permettent de découper un programme en unités réutilisables, similaires à des briques, que
l'on peut assembler de différentes manières pour créer des programmes plus complexes. Commençons par
créer ces "briques" et aborderons ensuite leur utilisation.

Créer et utiliser une fonction


Depuis le début de ce cours, nous avons déjà utilisé des fonctions, en particulier la fonction "main()". Cette
fonction est le point de départ de tous les programmes C++, c'est là que tout commence.

Code : C++
#include <iostream>
using namespace std;
int main() //Debut de la fonction main() et donc du programme
{
cout << "Bonjour tout le monde !" << endl;
return 0;
} //Fin de la fonction main() et donc du programme
Le programme démarre effectivement à la ligne 4 et se termine à la ligne 8 après l'accolade fermante. Cela
signifie que tout le code est contenu dans une seule et unique fonction. Il n'y a pas de sortie de cette
fonction. Le programme s'exécute de manière linéaire, sans sauts vers d'autres parties du code. Cependant,
comme vous l'avez mentionné, il est possible d'écrire d'autres fonctions, ce qui permet de découper le
programme en plusieurs modules indépendants.

Pourquoi vouloir faire cela ?

Découper un programme en fonctions est une pratique essentielle en programmation. Cela permet
d'organiser le code, de faciliter la collaboration entre développeurs et de réutiliser des morceaux de code.
Par exemple, une fonction comme sqrt() peut être utilisée à plusieurs endroits pour effectuer des calculs de
racine carrée sans répéter le même code.
Présentation des fonctions
Une fonction est un morceau de code qui accomplit une tâche particulière. Elle reçoit des données à traiter,
effectue des actions avec et enfin renvoie une valeur.
Les données entrantes s 'appellent des arguments et on utilise l'expression valeur retournée pour les éléments qui
sortent de la fonction (figure suivante).

Vous vous souvenez de pow() ? La fonction qui permet de calculer des puissances ? En utilisant le nouveau
vocabulaire, on
peut dire que cette fonction :
1. reçoit deux arguments ;
2. effectue un calcul mathématique ;
3. renvoie le résultat du calcul.
En utilisant un schéma comme le précédent, on peut représenter pow() comme à la figure suivante.
Vous pouvez réutiliser une fonction plusieurs fois, ce qui évite la duplication du code contenu dans la fonction
"pow()" chaque fois que vous avez besoin d'effectuer un calcul de puissance. Cette réutilisation simplifie le
code et améliore l'efficacité.
Définir une fonction
Définir une fonction est maintenant au programme. Plutôt que de vous laisser découvrir par vous-même en
examinant la fonction main(), je vais vous guider à travers le processus. Prêt ? Commençons ! Toutes les
fonctions ont une structure de base, comme suit :
Code : C++
type nomFonction(arguments)
{
//Instructions effectuées par la fonction
}
Une fonction est composée de trois éléments que j'ai déjà mentionnés, auxquels s'ajoute le nom de la fonction.
Le premier élément est le "type de retour", qui indique le type de variable renvoyée par la fonction. Par
exemple, si votre fonction doit renvoyer du texte, le type de retour sera "string", et si elle effectue un calcul, le
type de retour peut être "int" ou "double".
Une fonction est composée de trois éléments : le type de retour (indiquant le type de valeur renvoyée), le nom
de la fonction (décrivant son rôle), et la liste des arguments entre parenthèses (les données avec lesquelles la
fonction travaille). Le code de la fonction est contenu entre les accolades.
Il est possible de créer plusieurs fonctions ayant le même nom, à condition que la liste des arguments de ces fonctions
soit différente. Cette technique est appelée la "surcharge de fonction". Par exemple, dans un même programme, il peut
y avoir une fonction "int addition (int a, int b)" et une fonction "double addition(double a, double b)".
Les deux fonctions portent le même nom, mais l'une travaille avec des entiers et l'autre avec des nombres réels.

Créons donc des fonctions !


Une fonction toute simple
Commençons par une fonction simple. Cette fonction prend un nombre entier en entrée, ajoute 2 à ce
nombre, puis renvoie le résultat.
Code : C++
int ajouteDeux(int nombreRecu)
{
int valeur(nombreRecu + 2);
//On crée une case en mémoire
//On prend le nombre reçu en argument, on lui ajoute 2
//Et on met tout cela dans la mémoire
return valeur;
//On indique que la valeur qui sort de la fonction
//Est la valeur de la variable 'valeur'

Il n'y a pas de point-virgule ! Ni après la déclaration, ni après l'accolade fermante.


Passons en revue ce code en détail. Il y a deux lignes importantes à noter. La première ligne déclare
une fonction nommée "ajouteDeux" qui prend un nombre entier en argument et renvoie un nombre
entier une fois son exécution terminée.

Toutes les lignes suivantes utilisent des concepts que vous avez déjà rencontrés, à l'exception de
"return valeur;". Si vous avez des questions à ce sujet, je vous encourage à consulter le chapitre sur
l'utilisation de la mémoire pour plus de compréhension.

L'instruction return indique quelle valeur ressort de la fonction. En l'occurrence, c'est la valeur de la
variable valeur qui est renvoyée.
Appeler une fonction
Vous savez déjà comment appeler une fonction, car vous avez utilisé des fonctions mathématiques
précédemment !
Code : C++
#include <iostream>
using namespace std;
int ajouteDeux(int nombreRecu)
{
int valeur(nombreRecu + 2);
return valeur;
}
int main()
{
int a(2),b(2);
cout << "Valeur de a : " << a << endl;
cout << "Valeur de b : " << b << endl;
b = ajouteDeux(a); //Appel de la fonction
cout << "Valeur de a : " << a << endl;
cout << "Valeur de b : " << b << endl;
return 0;
}
On retrouve la syntaxe que l'on connaissait déjà : résultat = fonction(argument). Facile, pour ainsi dire !
Avez-vous essayé le programme ? Voici ce que cela donne :
Code : Console
Valeur de a : 2
Valeur de b : 2
Valeur de a : 2
Valeur de b : 4
Après l'appel à la fonction, la variable "b" a effectivement été modifiée, ce qui confirme que le programme
fonctionne comme prévu.
Plusieurs paramètres
Nous n'avons pas encore fini. Certaines fonctions prennent plusieurs paramètres, comme "pow()" et
"getline()" par exemple. Pour passer plusieurs paramètres à une fonction, il vous suffit de les séparer par
des virgules.
Code : C++
int addition(int a, int b)
{
return a+b;
}
double multiplication(double a, double b, double c)
{
return a*b*c;
}
La première de ces fonctions calcule la somme des deux nombres qui lui sont fournis en tant que
paramètres, tandis que la deuxième fonction calcule le produit des trois nombres reçus en tant
qu'arguments.
Vous pouvez bien sûr écrire des fonctions qui prennent des arguments de type différent.
Pas d'arguments
Inversement, il est tout à fait possible de créer des fonctions sans aucun argument en ne plaçant rien entre les
parenthèses.
Vous pourriez vous demander : "À quoi cela sert-il ?"
Pensez, par exemple, à une fonction qui demande à l'utilisateur d'entrer son nom. Elle n'aurait pas besoin de
paramètres car elle obtiendrait directement l'information de l'utilisateur.
Code : C++
string demanderNom()
{
cout << "Entrez votre nom : ";
string nom;
cin >> nom;
return nom;
}

Des fonctions qui ne renvoient rien


Il est possible d'écrire des fonctions qui ne renvoient rien, même si lors de leur déclaration, vous devez
spécifier un type "void". Ces fonctions n'ont rien à renvoyer.

Code : C++
void direBonjour()
{
cout << "Bonjour !" << endl;
//Comme rien ne ressort, il n'y a pas de return !
}
int main()
{
direBonjour();
//Comme la fonction ne renvoie rien
//On l'appelle sans mettre la valeur de retour dans une
Variable
return 0;
}
Il n'est pas possible de renvoyer plus d'une valeur à partir d'une fonction. Une fonction produit toujours au
maximum un résultat. Cela conclut la partie théorique. Dans la suite du chapitre, je vous montrerai quelques
exemples pratiques et un schéma récapitulatif pour une meilleure compréhension.
Quelques exemples
Le carré
Commençons par un exemple simple : le calcul du carré d'un nombre. Cette fonction prend un nombre x en
argument et renvoie la valeur de son carré .

Code : C++
#include <iostream>
using namespace std;
double carre(double x)
{
double resultat;
resultat = x*x;
return resultat;
}
int main()
{
double nombre, carreNombre;
cout << "Entrez un nombre : ";
cin >> nombre;
carreNombre = carre(nombre); //On utilise la fonction
cout << "Le carre de " << nombre << " est " << carreNombre <<
endl;
return 0;
}
Comme promis, voici un schéma pour comprendre ce qui se passe dans ce programme et l'ordre
d'exécution des lignes (voir la figure suivante).
Il est essentiel de se rappeler que les valeurs des variables transmises aux fonctions sont copiées dans de
nouvelles cases mémoire. Ainsi, la fonction carre() n'affecte pas les variables déclarées dans la fonction
main(). Elle travaille uniquement avec ses propres variables locales. C'est seulement lors du return que les
variables de main() sont modifiées, comme dans le cas de la variable carreNombre. La variable nombre reste
inchangée lors de l'appel à la fonction.
Réutiliser la même fonction
L'intérêt d'utiliser une fonction ici est bien sûr de pouvoir calculer facilement le carré de différents nombres,
par exemple de tous les nombres entre 1 et 20 :

Code : C++
#include <iostream>
using namespace std;
double carre(double x)
{
double resultat;
resultat = x*x;
return resultat;
}
int main()
{
for(int i(1); i<=20 ; i++)
{
cout << "Le carre de " << i << " est : " << carre(i) <<
endl;
}
return 0;
}
On écrit une seule fois la formule du calcul du carré et on utilise ensuite vingt fois cette « brique ». Ici, le
calcul est simple, mais dans bien des cas, utiliser une fonction raccourcit grandement le code !
Des variables avec le même nom
Dans le chapitre sur la mémoire, nous avions vu que chaque variable devait avoir un nom unique. C'est tout
à fait correct, mais cette règle n'est valable qu'à l'intérieur d'une même fonction. Il est tout à fait possible
d'avoir deux variables ayant le même nom, pour autant qu'elles soient déclarées dans des fonctions
différentes.
Code : C++
#include <iostream>
using namespace std;
double carre(double x)
{
double nombre;
nombre = x*x;
return nombre;
}
int main()
{
double nombre, carreNombre;
cout << "Entrez un nombre : ";
cin >> nombre;
carreNombre = carre(nombre); //On utilise la fonction
cout << "Le carre de " << nombre << " est " << carreNombre <<
endl;
return 0;
}
Comme vous pouvez le voir, il existe une variable appelée "nombre" dans la fonction main() et une autre dans la
fonction carre(). Le compilateur ne va pas poser de problème à cela, et ce code fonctionne de la même manière
que le précédent. Il n'y a pas de confusion possible entre les deux variables car le compilateur s'occupe d'une
fonction à la fois et ne considère pas les variables d'une fonction lorsqu'il traite l'autre.

Mais pourquoi faire ça ?


cout << "*";
}
cout << endl;
}
}
int main()
{
int largeur, hauteur;
cout << "Largeur du rectangle : ";
cin >> largeur;
cout << "Hauteur du rectangle : ";
cin >> hauteur;

dessineRectangle(largeur, hauteur);
return 0;
}
Une fois compilé ce programme s 'exécute et donne:
Code : Console
Largeur du rectangle : 16
Hauteur du rectangle : 3
****************
****************
****************
Voici une première version d'un logiciel de dessin basique. Cette fonction affiche simplement du texte et ne
retourne rien, d'où sa déclaration avec le type "void". Cependant, vous pouvez la modifier pour qu'elle
renvoie la surface du rectangle, auquel cas elle devra renvoyer un entier (int).
Vous pouvez également envisager deux améliorations :
• Afficher un message d'erreur si la hauteur ou la largeur du rectangle est négative.
• Ajouter un argument pour spécifier le symbole à utiliser dans le dessin.
Amusez-vous à expérimenter ces modifications. Il est essentiel de bien comprendre ces concepts pour
progresser en programmation.
Passage par valeur et passage par référence
La fin de ce chapitre est consacrée à trois notions un peu plus avancées. Vous pourrez toujours y revenir
plus tard si nécessaire

Passage par valeur


Commençons par discuter de la gestion de la mémoire par l'ordinateur dans le contexte des fonctions.
Nous allons prendre une fonction simple qui ajoute 2 à l'argument fourni, une fonction que vous
connaissez déjà. J'ai apporté quelques modifications mineures à cette fonction.
Code : C++
int ajouteDeux(int a)
{
a+=2;
return a;
Utiliser += ici est volontairement bizarre ! Vous verrez tout de suite pourquoi.

Voyons maintenant comment tester cette fonction. Le code suivant vous sera certainement familier :
Code : C++
#include <iostream>
using namespace std;
int ajouteDeux(int a)
{
a+=2;
return a;
}
int main()
{
int nombre(4), resultat;
resultat = ajouteDeux(nombre);

cout << "Le nombre original vaut : " << nombre << endl;
cout << "Le resultat vaut : " << resultat << endl;
return 0;
}
Cela donne sans surprise :
Code : Console
Le nombre original vaut : 4
Le resultat vaut : 6
L'étape intéressante se produit lors de la ligne resultat = ajouteDeux(nombre);. Il est utile de se rappeler des
schémas de la mémoire à ce stade. Lors de l'appel de la fonction, plusieurs étapes se déroulent :

• Le programme évalue la valeur de 'nombre' et trouve sa valeur actuelle.


• Le programme alloue un nouvel espace mémoire et y inscrit la valeur actuelle de 'nombre'. Cet espace
mémoire est étiqueté comme 'a', le nom de la variable dans la fonction.
• Le programme entre dans la fonction.
• Le programme ajoute 2 à la variable 'a'.
• La valeur de 'a' est ensuite copiée et attribuée à la variable 'resultat', qui a maintenant la valeur de 'a'.
• Ensuite, le programme sort de la fonction.
Il est important de noter que la variable 'nombre' est copiée dans une nouvelle case mémoire, ce qui signifie
que l'argument 'a' est passé par valeur. Pendant que le programme est à l'intérieur de la fonction, la mémoire
ressemble donc à ce qui est illustré dans le schéma de la figure suivante.
Nous avons maintenant trois cases en mémoire. Un autre point essentiel est que la variable
'nombre' reste inchangée. J'insiste sur ces points car il existe d'autres approches possibles.
Passage par référence
Vous souvenez-vous des références ? Oui, oui, ces concepts que j'ai expliqués il y a quelques
chapitres. Si vous n'êtes pas certains, n'hésitez pas à vous rafraîchir la mémoire. C'est maintenant
le moment de voir comment ces concepts s'appliquent. Au lieu de copier la valeur de 'nombre'
dans la variable 'a', il est possible d'attacher une "deuxième étiquette" à la variable 'nombre' à
l'intérieur de la fonction. Et bien sûr, c'est une référence que l'on doit utiliser comme argument de
la fonction.
Code : C++
int ajouteDeux(int& a) //Notez le petit & !!!
{
a+=2;
return a;
}
Quand on fait appel à la fonction, il n'y a plus de copie. Le programme crée simplement un alias
pour la variable 'nombre'. Examinons la mémoire dans ce scénario (voir figure suivante).
Maintenant, la variable 'a' et la variable 'nombre' sont identiques. Cela signifie que l'argument 'a' est
passé par référence.
Quel intérêt y a-t-il à faire un passage par référence ?

Ceci permet à la fonction ajouteDeux() de modifier ses arguments ! De cette manière, elle peut avoir un
impact persistant sur le reste du programme. Essayons de voir ce que cela donne. Reprenons le
programme précédent, mais en utilisant une référence comme argument. Cette fois-ci, nous obtenons :
Code : Console
Le nombre original vaut : 6
Le resultat vaut : 6
Qu'est-il arrivé ? C'est à la fois simple et complexe. Puisque 'a' et la variable 'nombre' pointent vers la
même zone mémoire, l'opération 'a += 2' a modifié la valeur de 'nombre' ! Il est donc crucial de faire
preuve de prudence lors de l'utilisation des références, car cela peut être potentiellement risqué. C'est
pourquoi on ne les utilise que lorsque cela est vraiment nécessaire.

Justement, est-ce qu'on pourrait avoir un exemple utile ?

Patience, j'y arrive. L'exemple classique est la fonction 'echange()'. Il s'agit d'une fonction qui échange
les valeurs de ses deux arguments fournis :
Code : C++
void echange(double& a, double& b)
{
double temporaire(a); //On sauvegarde la valeur de 'a'
a = b; //On remplace la valeur de 'a' par celle
de 'b'
b = temporaire; //Et on utilise la valeur sauvegardée
pour mettre l'ancienne valeur de 'a' dans 'b'
}
int main()
{
double a(1.2), b(4.5);
cout << "a vaut " << a << " et b vaut " << b << endl;
echange(a,b); //On utilise la fonction
cout << "a vaut " << a << " et b vaut " << b << endl;
return 0;
}
Ce code donne le résultat suivant :
Code : Console
a vaut 1.2 et b vaut 4.5
a vaut 4.5 et b vaut 1.2
Les valeurs des variables ont été échangées grâce au passage par référence, ce qui aurait été impossible
avec le passage par valeur. Expérimentez cette fonction avec et sans références pour mieux comprendre. Le
passage par référence peut sembler complexe au début, mais il est couramment utilisé. N'hésitez pas à
revenir à cette section plus tard si nécessaire.

Avancé : Le passage par référence constante


Le passage par référence offre un avantage majeur par rapport au passage par valeur : aucune copie n'est
effectuée. Cela sera particulièrement utile dans la suite du cours.
Utiliser le passage par référence au lieu du passage par valeur est plus efficace pour éviter la copie de chaînes
de caractères longues en mémoire, même si cela permet également la modification de l'argument, ce qui est
l'objectif des références.

Code : C++
void f1(string texte); //Implique une copie coûteuse de 'texte'
{
}
void f2(string& texte); //Implique que la fonction peut modifier
'texte'
{
}

La solution consiste à utiliser un passage par référence constante, ce qui évite la copie tout en empêchant la
modification de l'argument grâce à sa déclaration en tant que constant.
Code : C++
void f1(string const& texte); //Pas de copie et pas de
modification possible
{
}
Pour l'instant, cela peut sembler obscur et inutile, mais nous utiliserons cette technique fréquemment dans
la partie II du cours. Revenez-y quand vous aborderez cette section pour une meilleure compréhension.
Utiliser plusieurs fichiers
L'objectif des fonctions est de réutiliser des "briques" de code. Actuellement, ces fonctions sont souvent
situées près de la fonction main() et ne sont pas facilement réutilisables. En utilisant le C++, vous pouvez
diviser votre programme en plusieurs fichiers sources, chacun contenant des fonctions. Vous pouvez
ensuite inclure ces fichiers dans différents projets, créant ainsi des composants réutilisables pour
construire divers programmes.

Les fichiers nécessaires


Pour une organisation propre, vous avez besoin de deux fichiers : un fichier source avec l'extension .cpp
contenant le code source de la fonction, et un fichier d'en-tête avec l'extension .h qui contient uniquement la
description de la fonction, ce que l'on appelle le prototype de la fonction. Créons donc ces deux fichiers
pour notre fonction bien connue, ajouteDeux().

Code : C++
int ajouteDeux(int nombreRecu)
{
int valeur(nombreRecu + 2);
return valeur;
}
Le fichier source
C'est la partie la plus simple des deux. Vous pouvez accéder à cela via les menus "File > New > File". Ensuite,
choisissez "C/C++ source" (voir la figure suivante).

Cliquez sur "Go", choisissez C++ lorsque vous êtes invité à le faire, donnez un nom significatif comme
"math.cpp" pour votre fichier, et cochez toutes les options (voir la figure suivante). Assurez-vous que le
fichier est dans le même dossier que votre fichier "main.cpp".
Cliquez sur "Finish". Votre fichier source est maintenant créé. Passons maintenant au fichier d'en-tête.
Le fichier d'en-tête
Le début est presque identique. Allez dans les menus "File > New > File", puis sélectionnez "C/C++
header" (voir la figure suivante).
Dans la fenêtre suivante, nommez le fichier en utilisant le même nom que le fichier source, mais avec
l'extension .h à la place de .cpp. Par exemple, nommez-le "math.h" et placez-le dans le même dossier que
les deux autres fichiers. Ne modifiez pas le champ en-dessous et cochez toutes les options (voir la figure
suivante)
Cliquez sur "Finish". Voilà, une fois que les deux fichiers sont créés, vous devriez les voir apparaître
dans la colonne de gauche de Code::Blocks (voir la figure suivante).
Le nom du projet sera certainement différent dans votre cas.

Déclarer la fonction dans les fichiers


Maintenant que vous avez vos fichiers, il ne vous reste plus qu'à les compléter.
Le fichier source
Je vous ai expliqué que le fichier source contient la définition de la fonction. C'est l'un des éléments.
L'autre élément plus complexe est la nécessité d'indiquer au compilateur que les fichiers .cpp et .h sont liés.
Pour ce faire, commencez le fichier .cpp avec cette ligne :
cpp
#include "math.h"
Vous devez reconnaître cette ligne. Elle indique que nous allons utiliser ce qui se trouve dans le fichier
math.h.
Il faut utiliser ici des guillemets " et non des chevrons < et > comme vous en aviez l'habitude jusque
là.
Le fichier math.cpp au complet est donc :
Code : C++
#include "math.h"
int ajouteDeux(int nombreRecu)
{
int valeur(nombreRecu + 2);
return valeur;
}
Le fichier d'en-tête
Si vous regardez le fichier qui a été créé, vous remarquerez qu'il n'est pas vide. Il contient trois lignes
mystérieuses :
Code : C++
#ifndef MATH_H_INCLUDED
#define MATH_H_INCLUDED
#endif // MATH_H_INCLUDED
Ces lignes servent à éviter une inclusion multiple du fichier par le compilateur, ce qui pourrait provoquer
des problèmes de boucle. Il est essentiel de laisser ces lignes intactes et de placer tout le code entre la
deuxième et la troisième ligne.
Le texte en majuscules variera pour chaque fichier, il correspond au contenu présent dans un champ non modifié
lors de la création du fichier. Si vous n'utilisez pas Code::Blocks, ces lignes peuvent ne pas être
automatiquement présentes dans vos fichiers, vous devrez donc les ajouter manuellement. Le mot en majuscules
doit être identique sur les trois lignes où il apparaît, mais chaque fichier doit utiliser un mot différent.
Dans ce fichier, vous devez insérer ce qu'on appelle le prototype de la fonction. Il s'agit de la première ligne
de la fonction, située avant les accolades. Vous devez copier le texte de cette ligne et ajouter un point-
virgule à la fin. Cela se résume donc en une opération très concise. Voici le résultat que nous obtenons
pour notre fonction :
Code : C++
#ifndef MATH_H_INCLUDED
#define MATH_H_INCLUDED
int ajouteDeux(int nombreRecu);
#endif // MATH_H_INCLUDED
N'oubliez pas le point-virgule ici !
Ceci couvre la situation la plus simple. Si vous utilisez des variables d'argument plus complexes, telles que
des chaînes de caractères (ceci s'applique également aux tableaux, que nous examinerons dans le prochain
chapitre), vous devrez ajouter la ligne d'inclusion correspondante.
#include
<string> avant le prototype. On aura ainsi:
Code : C++
#ifndef MATH_H_INCLUDED
#define MATH_H_INCLUDED
#include <string>
void afficherMessage(std::string message);
#endif // MATH_H_INCLUDED
L'autre point essentiel consiste à ajouter "std::" devant "string", indiquant l'espace de nom. Cette distinction
est nécessaire car nous n'utilisons pas "using namespace std" ici, par choix. Par conséquent, nous utilisons
"std::string" au lieu de simplement "string". Une fois cela fait, il ne reste qu'à inclure ces éléments dans le
fichier "main.cpp" pour que le compilateur puisse trouver la fonction "ajouteDeux()" lors de son utilisation.
Code : C++
#include "math.h"
Cela donne :
Code : C++
#include <iostream>
#include "math.h"
using namespace std;
int main()
{
int a(2),b(2);
cout << "Valeur de a : " << a << endl;
cout << "Valeur de b : " << b << endl;
b = ajouteDeux(a); //Appel de la fonction
cout << "Valeur de a : " << a << endl;
cout << "Valeur de b : " << b << endl;
return 0;
}

L'inclusion se fait toujours avec le fichier d'en-tête (.h), jamais avec le fichier source (.cpp).
Et voilà ! Nous disposons maintenant de composants autonomes que nous pouvons réutiliser dans plusieurs
projets. Si vous souhaitez utiliser la fonction "ajouteDeux()" dans un autre projet, il vous suffira de copier les
fichiers "math.cpp" et "math.h".

On peut regrouper plusieurs fonctions dans un même fichier, souvent classées par catégories, comme les fonctions
mathématiques, les fonctions d'affichage de menu, ou les fonctions de déplacement pour un jeu vidéo. L'organisation
est essentielle en programmation.

Documenter son code


Avant de conclure, il est essentiel de noter l'importance de documenter votre code avec des commentaires,
en particulier pour les fonctions que d'autres programmeurs pourraient utiliser. Dans les fichiers d'en-tête,
on décrit généralement trois éléments : ce que fait la fonction, ses arguments et la valeur qu'elle renvoie.
Par exemple, voici une documentation concise pour la fonction "ajouteDeux()":
Code : C++
#ifndef MATH_H_INCLUDED
#define MATH_H_INCLUDED
/*
* Fonction qui ajoute 2 au nombre reçu en argument
* - nombreRecu : Le nombre auquel la fonction ajoute 2
* Valeur retournée : nombreRecu + 2
*/
int ajouteDeux(int nombreRecu);
#endif // MATH_H_INCLUDED
Naturellement, dans cet exemple, la description est très simple. Cependant, il est crucial de prendre l'habitude
de documenter votre code. Il est tellement courant d'ajouter des commentaires dans les fichiers .h que des
systèmes quasi-automatisés existent pour générer des sites web ou des livres à partir de ces commentaires.
Le célèbre système Doxygen, par exemple, utilise la notation suivante :
Code : C++
/**
* \brief Fonction qui ajoute 2 au nombre
reçu en argument
* \param nombreRecu Le nombre auquel la
fonction ajoute 2
* \return nombreRecu + 2
*/
int ajouteDeux(int nombreRecu);
À ce stade, cela peut sembler un peu superflu, mais vous comprendrez dans la partie III de ce cours à quel
point une documentation efficace est cruciale. Vous êtes libre de choisir la notation qui vous convient le
mieux.
Des valeurs par défaut pour les arguments
Vous avez maintenant une idée des arguments de fonction, car j'en ai parlé tout au long du chapitre.
Cependant, je vais vous montrer que cela peut varier avec la fonction suivante :
Code : C++
int nombreDeSecondes(int heures, int minutes, int secondes)
{
int total = 0;
total = heures * 60 * 60;
total += minutes * 60;
total += secondes;
return total;
}
Cette fonction convertit heures, minutes et secondes en un nombre total de secondes. Les variables "heures,"
"minutes," et "secondes" sont les paramètres d'entrée de la fonction.
Les valeurs par défaut
La nouveauté ici, c'est la possibilité de donner des valeurs par défaut à certains paramètres de fonction, ce qui
évite de devoir spécifier tous les paramètres à chaque appel. Pour mieux comprendre, examinons le code
complet et essayons-le dans votre IDE.
Code : C++
#include <iostream>
using namespace std;
// Prototype de la fonction
int nombreDeSecondes(int heures, int minutes, int secondes);
// Main
int main()
{
cout << nombreDeSecondes(1, 10, 25) << endl;
return 0;
}
// Définition de la fonction
int nombreDeSecondes(int heures, int minutes, int secondes)
{
int total = 0;
total = heures * 60 * 60; total += minutes * 60;
total += secondes;
return total;
}
Ce code donne le résultat suivant :
Code : Console
4225
Sachant que 1 heure = 3600 secondes, 10 minutes = 600 secondes, 25 secondes =… 25 secondes, le résultat
est logique car
Pour rendre certains paramètres facultatifs, comme les heures, vous pouvez utiliser ces valeurs par défaut :

Heures (par défaut) : 0


Minutes (par défaut) : 0
Secondes
Code : C++ (par défaut) : 0
int nombreDeSecondes(int heures, int minutes = 0, int secondes = 0);
Dans cet exemple, seul le paramètre "heures" sera obligatoire, tandis que les deux autres deviennent
facultatifs. Si les minutes et les secondes ne sont pas spécifiées, elles prendront la valeur 0 par défaut dans la
fonction. Voici le code complet que vous devriez avoir :
Code : C++
#include <iostream>
using namespace std;
// Prototype avec les valeurs par défaut
int nombreDeSecondes(int heures, int minutes = 0, int secondes = 0);
// Main
int main()
{
cout << nombreDeSecondes(1, 10, 25) << endl;
return 0;
}
// Définition de la fonction, SANS les valeurs par défaut
int nombreDeSecondes(int heures, int minutes, int secondes)
{
int total = 0;
total = heures * 60 * 60;
total += minutes * 60;
total += secondes;
return total;
}
Une remarque importante : spécifiez les valeurs par défaut uniquement dans le prototype de la fonction,
généralement dans le fichier d'en-tête (.h), surtout si votre code est divisé en plusieurs fichiers. Une erreur à ce sujet
provoquerait une erreur de compilation à la ligne de la définition de la fonction.
Ce code ne diffère pas beaucoup de l'exemple précédent. À l'exception des valeurs par défaut dans le
prototype, rien n'a été modifié (et le résultat affiché à l'écran reste inchangé). La nouveauté réside dans la
possibilité de supprimer des paramètres lors de l'appel de la fonction (comme dans le "main()"). Par exemple,
vous pouvez écrire :
Code : C++
cout << nombreDeSecondes(1) << endl;
Le compilateur lit les paramètres de gauche à droite. Avec un seul argument et les heures obligatoires, il
interprète "1" comme le nombre d'heures. Le résultat affiché à l'écran sera :
Code : Console
3600

Mieux encore, vous avez la possibilité de spécifier uniquement les heures et les minutes si vous le souhaitez
:
Code : C++
cout << nombreDeSecondes(1, 10) << endl;
Code : Console
4200
Tant que vous indiquez au moins les paramètres obligatoires, il n'y a pas de problème.

Cas particuliers, attention danger


Effectivement, même si cela semble simple, il y a quelques subtilités à considérer. Explorons ces pièges
sous la forme de questions et réponses :
Et si je veux envoyer à la fonction juste les heures et les secondes, mais pas les minutes ?
Effectivement, tel que c'est actuellement configuré, cela n'est pas possible. Le compilateur analyse les
paramètres de gauche à droite, assignant le premier aux heures, le deuxième aux minutes, et le troisième aux
secondes.
Vous ne pouvez PAS écrire :
Code : C++
cout << nombreDeSecondes(1,,25) << endl;
Exactement, il est interdit de "sauter" des paramètres, même s'ils sont facultatifs en C++. Si vous souhaitez
spécifier le premier et le dernier paramètre, vous devrez inévitablement fournir les valeurs pour ceux du
milieu. Vous devrez donc écrire :

Code : C++
cout << nombreDeSecondes(1, 0, 25) << endl;
Est-ce que je peux rendre seulement les heures facultatives, et rendre les minutes et secondes obligatoires ?

Si le prototype est défini dans le même ordre que précédemment, alors non, cela ne fonctionnera pas. Les
paramètres facultatifs doivent toujours être placés à la fin (à droite). Le code que vous avez mentionné ne se
compilera pas :
Code : C++
int nombreDeSecondes(int heures = 0, int minutes, int secondes)//Erreur, les
paramètres par défaut doivent être à droite
La solution pour résoudre ce problème est de placer le paramètre "heures" à la fin du prototype de la fonction
:
Code : C++
int nombreDeSecondes(int secondes, int minutes, int heures = 0);
//OKEst-ce que je peux rendre tous mes paramètres facultatifs ?

Oui, cela fonctionne correctement :


Code : C++
int nombreDeSecondes(int heures = 0, int minutes = 0, int secondes =
0);
Dans ce cas, l'appel de la fonction peut s'écrire de la manière suivante :
Code : C++

cout << nombreDeSecondes() << endl;


Dans ce cas, le résultat renvoyé sera bien évidemment 0, comme indiqué ci-dessus.
Règles à retenir
En résumé, retenez ces deux règles importantes pour les valeurs par défaut :

1. Seul le prototype de la fonction doit contenir les valeurs par défaut, pas sa définition.
2. Les valeurs par défaut doivent être placées à la fin de la liste des paramètres, c'est-à-dire à droite.
En résumé
Une fonction est une portion de code qui accomplit une tâche spécifique. Tous les programmes ont au
moins une fonction, généralement main(), qui démarre le programme. Organiser le code en fonctions
distinctes améliore la lisibilité. Les fonctions peuvent prendre des arguments en entrée, renvoyer des
résultats via return, et même modifier des données en mémoire avec des références.

Pour les programmes complexes, il est conseillé d'organiser les fonctions dans des fichiers séparés. Les
fichiers .cpp contiennent les définitions de fonctions, tandis que les fichiers .h fournissent les prototypes
pour annoncer l'existence des fonctions à d'autres parties du programme.
Les tableaux
Dans de nombreux programmes, vous avez souvent besoin de regrouper des variables du même type qui ont
des rôles similaires. Par exemple, une liste d'utilisateurs sur un site web nécessite de nombreuses variables de
type "string", ou les dix meilleurs scores d'un jeu sont stockés dans différentes cases mémoire, toutes de type
"int". En C++, comme dans la plupart des langages, vous pouvez utiliser des tableaux pour regrouper ces
données.

Dans ce chapitre, nous allons vous apprendre à manipuler deux types de tableaux : ceux de taille fixe, où la taille
est connue à l'avance (comme la liste des dix meilleurs scores), et ceux de taille variable, qui peuvent grandir ou
rétrécir en permanence (comme la liste des visiteurs d'un site web). Nous commencerons par les tableaux de
taille fixe, car ils sont plus simples à utiliser.
Les tableaux statiques
Dans l'introduction, j'ai souligné l'intérêt des tableaux pour regrouper des variables du même type. Prenons un
exemple concret : la liste des meilleurs scores d'un jeu que vous pourriez créer un jour.
Un exemple d'utilisation
Pour afficher les 5 meilleurs scores des joueurs, vous avez besoin de deux listes : une pour les noms des
joueurs et une pour leurs scores. Cela implique la déclaration de 10 variables pour stocker ces informations en
mémoire, par exemple :
Code : C++
string nomMeilleurJoueur1("Nanoc");
string nomMeilleurJoueur2("M@teo21");
string nomMeilleurJoueur3("Albert Einstein");
string nomMeilleurJoueur4("Isaac Newton");
string nomMeilleurJoueur5("Archimede");
int meilleurScore1(118218);
int meilleurScore2(100432);
int meilleurScore3(87347);
int meilleurScore4(64523);
int meilleurScore5(31415);
Et pour afficher tout cela:
Code : C++
cout << "1) " << nomMeilleurJoueur1 << " " << meilleurScore1 <<
endl;
cout << "2) " << nomMeilleurJoueur2 << " " << meilleurScore2 <<
endl;
cout << "3) " << nomMeilleurJoueur3 << " " << meilleurScore3 <<
endl;
cout << "4) " << nomMeilleurJoueur4 << " " << meilleurScore4 <<
endl;
cout << "5) " << nomMeilleurJoueur5 << " " << meilleurScore5 <<
endl;
En effet, cela représente un grand nombre de lignes ! Si vous souhaitiez afficher les 100 meilleurs scores au lieu
des 5 premiers, cela nécessiterait la déclaration de 200 variables et la rédaction de près de 100 lignes quasi
identiques pour l'affichage, ce qui serait fastidieux.

Les tableaux viennent à la rescousse. Ils permettent de déclarer les 100 meilleurs scores et les noms des 100
meilleurs joueurs en une seule étape, en créant une seule zone en mémoire pour stocker les 100 entiers et une
autre pour les noms. C'est une méthode bien plus efficace pour gérer ces données.
Effectivement, il est essentiel que les variables regroupées dans un tableau aient un lien ou une relation entre
elles. Il ne serait pas approprié de mettre l'âge de votre chien et le nombre d'internautes connectés dans le même
tableau, même s'ils sont tous les deux de type "int". Un tableau doit contenir des données similaires ou associées
pour une utilisation appropriée.
Dans cet exemple, nous avons besoin de 100 emplacements dans le tableau, ce que l'on appelle sa "taille".
Lorsque la taille du tableau est constante et définie dans le code source, on parle d'un "tableau statique", ce
qui convient parfaitement à notre liste des 100 meilleurs scores.
Déclarer un tableau statique
En C++, comme toujours, une variable est composée d'un nom et d'un type. Cette règle reste valable pour les
tableaux, mais il y a une propriété supplémentaire à prendre en compte : la taille du tableau, c'est-à-dire le
nombre de compartiments que la mémoire allouée au tableau peut contenir.

La déclaration d'un tableau ressemble beaucoup à celle d'une variable, comme illustré dans l'exemple suivant :

On spécifie d'abord le type de données, puis le nom que vous choisissez pour le tableau, suivi de crochets
contenant la taille du tableau. Voici un exemple pour illustrer cette déclaration :
Code : C++
#include <iostream>
using namespace std;
int main()
{
int meilleurScore[5]; //Déclare un tableau de 5 int
double anglesTriangle[3]; //Déclare un tableau de 3 double
return 0;
}
Pour comprendre comment cela fonctionne en termes de mémoire, jetons un coup d'œil à l'un de nos
schémas habituels, comme illustré dans la figure suivante :
Dans le schéma, vous pouvez voir deux zones mémoire avec des étiquettes. Chaque zone est divisée en cases
: trois pour le tableau "anglesTriangle" et cinq pour le tableau "meilleurScore". Actuellement, aucune de ces
cases n'est initialisée, ce qui signifie qu'elles contiennent des valeurs aléatoires.

Vous pouvez également déclarer un tableau en utilisant une constante de type "int" ou "unsigned int" comme
taille en plaçant simplement le nom de la constante entre les crochets au lieu d'un nombre.
Code : C++
int const tailleTableau(20); //La taille du tableau
double anglesIcosagone[tailleTableau];
Il faut impérativement utiliser une constante comme taille du tableau.
Il est recommandé d'utiliser des constantes pour définir les tailles de vos tableaux plutôt que d'indiquer
directement la taille entre les crochets. C'est une bonne pratique. Maintenant que l'espace en mémoire est
réservé, passons à son utilisation.
Accéder aux éléments d'un tableau
Chaque case d'un tableau peut être utilisée comme une variable ordinaire, sans distinction. L'accès se fait en
spécifiant le nom du tableau suivi du numéro de la case. Par exemple, dans le tableau "meilleurScore", vous
pouvez accéder aux cinq variables en indiquant la première case, la deuxième, et ainsi de suite jusqu'à la
cinquième.

Pour accéder à une case, vous utilisez la syntaxe suivante : nomDuTableau[numeroDeLaCase]. Il y a cependant
une subtilité : la première case a le numéro 0, et non 1. Les indices sont décalés de 1. Par exemple, pour
accéder à la troisième case de "meilleurScore" et y stocker une valeur, vous écririez :
Code : C++
meilleurScore[2] = 5;
En effet, ;
la troisième case possède donc le numéro 2. Si je veux remplir mon tableau des meilleurs scores comme
dans l'exemple initial, je peux donc écrire :

Code : C++
int const nombreMeilleursScores(5);//La taille du tableau
int meilleursScores[nombreMeilleursScores]; //Déclaration du
tableau
meilleursScores[0] = 118218; //Remplissage de la première case
meilleursScores[1] = 100432; //Remplissage de la deuxième case
meilleursScores[2] = 87347; //Remplissage de la troisième case
meilleursScores[3] = 64523; //Remplissage de la quatrième case
meilleursScores[4] = 31415; //Remplissage de la cinquième case

Comme tous les numéros de cases sont décalés, la dernière case a le numéro 4 et pas 5 !
Parcourir un tableau
Le gros point fort des tableaux, c'est qu'on peut les parcourir en utilisant une boucle. On peut ainsi effectuer
une action sur chacune des cases d'un tableau, l'une après l'autre : par exemple afficher le contenu des cases.
On connaît a priori le nombre de cases du tableau, on peut donc utiliser une boucle for. Nous allons pouvoir
utiliser la variable i de la boucle pour accéder au ième élément du tableau. C'est fou, on dirait que c'est fait pour
!
Code : C++
int const nombreMeilleursScores(5); //La taille dutableau
int meilleursScores[nombreMeilleursScores]; //Déclaration du
tableau
meilleursScores[0] = 118218; //Remplissage de la première case
meilleursScores[1] = 100432; //Remplissage de la deuxième case
meilleursScores[2] = 87347; //Remplissage de la troisième case
meilleursScores[3] = 64523; //Remplissage de la quatrième case
meilleursScores[4] = 31415; //Remplissage de la cinquième case
for(int i(0); i<nombreMeilleursScores; ++i)
{
cout << meilleursScores[i] << endl;
La variable i prend successivement les valeurs 0, 1, 2, 3 et 4, ce qui veut dire que les valeurs de
meilleursScores[0], puis meilleursScores[1], etc. sont envoyées dans cout.
Il faut faire très attention, dans la boucle, à ne pas dépasser la taille du tableau, sous peine de voir votre
programme planter. La dernière case dans cet exemple a le numéro nombreMeilleursScores moins un.
Les valeurs autorisées de i sont tous les entiers entre 0 et nombreMeilleursScores moins un compris.
Vous allez voir, le couple tableau / boucle for va devenir votre nouveau meilleur ami. En tout cas, je l'espère :
c'est un outil très puissant.
Un petit exemple
Allez, je vous propose un petit exemple légèrement plus complexe. Nous allons utiliser le C++ pour calculer la
moyenne de vos notes de l'année. Je vous propose de mettre toutes vos notes dans un tableau et d'utiliser
une boucle for pour le calcul de la moyenne. Voyons donc tout cela étape par étape. La première étape
consiste à déclarer un tableau pour stocker les notes. Comme ce sont des nombres à virgule, il nous faut des
double.
Code : C++
int const nombreNotes(6);
double notes[nombreNotes];
La deuxième étape consiste à remplir ce tableau avec vos notes.
J'espère que vous savez encore comment faire !
Code : C++
int const nombreNotes(6);
double notes[nombreNotes];
notes[0] = 12.5;
notes[1] = 19.5; //Bieeeen !
notes[2] = 6.; //Pas bien !
notes[3] = 12;
notes[4] = 14.5;
notes[5] = 15;

Je me répète, mais c'est important : la première case du tableau a le numéro 0, la deuxième le numéro 1, et ainsi de
suite.

Pour calculer la moyenne, il nous faut additionner toutes les notes puis diviser le résultat obtenu par le
nombre de notes. Nous connaissons déjà le nombre de notes, puisque nous avons la constante
nombreNotes. Il ne reste donc qu'à déclarer une variable pour contenir la moyenne.
Le calcul de la somme s 'effectue dans une boucle for qui parcourt toutes les cases du tableau.
Code : C++
Double moyenne(0);
for(int i(0); i<nombreNotes; ++i)
{
moyenne += notes[i]; //On additionne toutes les notes
}
//En arrivant ici, la variable moyenne contient la somme des notes
(79.5)
//Il ne reste donc qu'à diviser par le nombre de notes
moyenne /= nombreNotes;
Avec une petite ligne pour l'affichage de la valeur, on obtient le résultat voulu : un programme qui calcule la
moyenne de vos notes.
Code : C++
#include <iostream>
using namespace std;
int main()
{
int const nombreNotes(6);
double notes[nombreNotes];
notes[0] = 12.5;
notes[1] = 19.5; //Bieeeen !
notes[2] = 6.; //Pas bien !
notes[3] = 12;
notes[4] = 14.5;
notes[5] = 15;

double moyenne(0);
for(int i(0); i<nombreNotes; ++i)
{
moyenne += notes[i]; //On additionne toutes les notes
}
//En arrivant ici, la variable moyenne contient la somme des
notes (79.5)
//Il ne reste donc qu'à diviser par le nombre de notes
moyenne /= nombreNotes;

cout << "Votre moyenne est : " << moyenne << endl;
return 0;
}

Voyons ce que cela donne quand on l'exécute :


Code : Console
Votre moyenne est : 13.25
Et cela marche ! Mais vous n'en doutiez pas, bien sûr ?
Les tableaux et les fonctions
Comme vous allez le voir, les tableaux et les fonctions ne sont pas les meilleurs amis du monde.
La première restriction est qu'on ne peut pas écrire une fonction qui renvoie un tableau statique. C'est
impossible. La deuxième restriction est qu'un tableau statique est toujours passé par référence. Et il n'y a
pas besoin d'utiliser l'esperluette (&) : c'est fait automatiquement. Cela veut dire que, lorsqu'on passe un
tableau à une fonction, cette dernière peut le modifier. Voici donc une fonction qui reçoit un tableau en
argument.

Code : C++
void fonction(double tableau[])
{
//…
}

Il ne faut rien mettre entre les crochets.

Mais ce n'est pas tout ! Très souvent, on veut parcourir le tableau, avec une boucle for par exemple. Il nous
manque une information cruciale. Vous voyez laquelle ?
La taille ! À l'intérieur de la fonction précédente, il n'y a aucun moyen de connaître la taille du tableau ! Il faut
donc impérativement ajouter un deuxième argument contenant la taille. Cela donne :
Pour vous entraîner, je vous propose d'écrire une fonction moyenne() qui calcule la moyenne des valeurs
d'un tableau. Voici ma version :
Code : C++
/*
* Fonction qui calcule la moyenne des éléments d'un tableau
* - tableau: Le tableau dont on veut la moyenne
* - tailleTableau: La taille du tableau
*/
double moyenne(double tableau[], int tailleTableau)
{
double moyenne(0);
for(int i(0); i<tailleTableau; ++i)
{
moyenne += tableau[i]; //On additionne toutes les valeurs
}
moyenne /= tailleTableau;
return moyenne;
}
Assez parlé de ces tableaux. Passons à la suite.
Les tableaux dynamiques
Je vous avais dit que nous allions parler de deux sortes de tableaux : ceux dont la taille est fixée et ceux dont la
taille peut varier,les tableaux dynamiques . Certaines choses sont identiques, ce qui va nous éviter de tout
répéter.
Déclarer un tableau dynamique
La première différence se situe au tout début de votre programme. Il faut ajouter la ligne #include <vector>
pour utiliser ces tableaux.

à cause de cette ligne, on parle souvent de vector à la place de tableau dynamique. J'utiliserai parfois ce terme
dans la suite
La deuxième grosse différence se situe dans la manière de déclarer un tableau. On utilise la syntaxe présentée
en figure suivante.

Par exemple, pour un tableau de 5 entiers, on écrit :


Code : C++
#include <iostream>
#include <vector> //Ne pas oublier !
using namespace std;
int main()
{
vector<int> tableau(5);
return 0;
}
Il faut ici remarquer trois choses :
1. le type n'est pas le premier mot de la ligne, contrairement aux autres variables ;
2. on utilise une notation bizarre avec un chevron ouvrant et un chevron fermant ;
3. on écrit la taille entre parenthèses et non entre crochets.
Cela veut dire que les choses ne ressemblent pas vraiment aux tableaux statiques. Cependant, vous allez voir
que, pour parcourir le tableau, le principe est similaire. Mais avant cela, il y a deux astuces bien pratiques à
savoir.
On peut directement remplir toutes les cases du tableau en ajoutant un deuxième argument entre les
parenthèses :
Code : C++
vector<int> tableau(5, 3); //Crée un tableau de 5 entiers valant
tous 3
vector<string> listeNoms(12, "Sans nom");
//Crée un tableau de 12 strings valant toutes « Sans nom »
On peut déclarer un tableau sans cases en ne mettant pas de parenthèses du tout :
Code : C++
vector<double> tableau; //Crée un tableau de 0 nombre à virgule

uh… À quoi sert un tableau vide ?


Rappelez-vous que ce sont des tableaux dont la taille peut varier. On peut donc ajouter des cases par la suite.
Attendez un peu et vous saurez tout.
Accéder aux éléments d'un tableau
La déclaration était très différente des tableaux statiques. Par contre, l'accès est exactement identique. On
utilise à nouveau les crochets et la première case possède aussi le numéro 0. On peut donc réécrire l'exemple
de la section précédente avec un vector :
Code : C++
int const nombreMeilleursScores(5); //La taille du tableau
vector<int> meilleursScores(nombreMeilleursScores); //Déclaration
du tableau
meilleursScores[0] = 118218; //Remplissage de la première case
meilleursScores[1] = 100432; //Remplissage de la deuxième case
meilleursScores[2] = 87347; //Remplissage de la troisième case
meilleursScores[3] = 64523; //Remplissage de la quatrième case
meilleursScores[4] = 31415; //Remplissage de la cinquième case

Là, je crois qu'on ne peut pas faire plus facile.


Changer la taille
Entrons maintenant dans le vif du sujet : faire varier la taille d'un tableau. Commençons par ajouter des cases
à la fin d'un tableau. Il faut utiliser la fonction push_back(). On écrit le nom du tableau, suivi d'un point et du
mot push_back avec, entre parenthèses, la valeur qui va remplir la nouvelle case.
Code : C++
vector<int> tableau(3,2); //Un tableau de 3 entiers valant tous 2
tableau.push_back(8);
//On ajoute une 4ème case au tableau qui contient la valeur 8
Voyons de plus près ce qui se passe dans la mémoire (figure suivante).
Une case supplémentaire a été ajoutée au bout du tableau, de manière automatique. C'est fou ce que cela peut
être intelligent un ordinateur parfois. Et bien sûr on peut ajouter beaucoup de cases à la suite les unes des
autres.
Code : C++
vector<int> tableau(3,2); //Un tableau de 3 entiers valant tous 2
tableau.push_back(8); //On ajoute une 4ème case qui contient la
valeur 8
tableau.push_back(7); //On ajoute une 5ème case qui contient la
valeur 7
tableau.push_back(14); //Et encore une avec le nombre 14 cette fois
//Le tableau contient maintenant les nombres : 2 2 2 8 7 14
Et ils ne peuvent que grandir, les vectors ?

Non ! Bien sûr que non. Les créateurs du C++ ont pensé à tout.
On peut supprimer la dernière case d'un tableau en utilisant la fonction pop_back() de la même manière
que push_back(),
sauf qu'il n'y a rien à mettre entre les parenthèses.
Code : C++
vector<int> tableau(3,2); //Un tableau de 3 entiers valant tous 2
tableau.pop_back(); //Et hop ! Plus que 2 cases
tableau.pop_back(); //Et hop ! Plus que 1 case
Attention tout de même à ne pas trop supprimer de cases ! Un tableau ne peut pas contenir moins de 0 éléments.

Il nous reste quand même un petit problème à régler. Comme la taille peut changer, on ne sait pas de
manière certaine combien d'éléments contient un tableau. Heureusement, il y a une fonction pour cela :
size(). Avec tableau.size(), on récupère un entier correspondant au nombre d'éléments de tableau.
Code : C++
vector<int> tableau(5,4); //Un tableau de 5 entiers valant tous 4
int const taille(tableau.size());
//Une variable qui contient la taille du tableau
//La taille peut varier mais la valeur de cette variable ne
changera pas
//On utilise donc une constante
//À partir d'ici, la constante 'taille' vaut donc 5

Retour sur l'exercice


Je crois que le mieux, pour se mettre tout cela en tête, est de reprendre l'exercice du calcul des moyennes
mais en le réécrivant à la « sauce vector ».
Je vous laisse essayer. Si vous n'y arrivez pas, voici ma solution :
Code : C++
#include <iostream>
#include <vector> //Ne pas oublier !
using namespace std;
int main()
{
vector<double> notes; //Un tableau vide
notes.push_back(12.5); //On ajoute des cases avec les notes
notes.push_back(19.5);
notes.push_back(6);
notes.push_back(12);
notes.push_back(14.5);
notes.push_back(15);
double moyenne(0);
for(int i(0); i<notes.size(); ++i)
//On utilise notes.size() pour la limite de notre boucle
{
moyenne += notes[i]; //On additionne toutes les notes
}
moyenne /= notes.size();
//On utilise à nouveau notes.size() pour obtenir le nombre de
notes

cout << "Votre moyenne est : " << moyenne << endl;
return 0;
}
on a écrit deux programmes qui font exactement la même chose de deux manières différentes. C'est très
courant, il y a presque toujours plusieurs manières de faire les choses. Chacun choisit celle qu'il préfère.
Les vector et les fonctions
Passer un tableau dynamique en argument à une fonction est beaucoup plus simple que pour les tableaux
statiques. Comme pour n'importe quel autre type, il suffit de mettre vector<type> en argument. Et c'est
tout. Grâce à la fonction size(), il n'y a même pas besoin d'ajouter un deuxième argument pour la taille du
tableau !
Cela donne tout simplement :
Code : C++
//Une fonction recevant un tableau d'entiers en argument
void fonction(vector<int> a)
{
//…
}
Simple non ? Mais on peut quand même faire mieux. Je vous ai parlé, au chapitre précédent, du passage
par référence constante pour optimiser la copie. En effet, si le tableau contient beaucoup d'éléments, le
copier prendra du temps. Il vaut donc mieux utiliser cette astuce, ce qui donne :
Code : C++
/Une fonction recevant un tableau d'entiers en argument
void fonction(vector<int> const& a)
{
//…
}
Dans ce cas, le tableau dynamique ne peut pas être modifié. Pour changer le contenu du tableau, il faut utiliser un
passage par référence tout simple (sans le const donc).
Pour appeler une fonction recevant un vector en argument, il n'y a rien de particulier à faire. Comme dans le
cas des variables du chapitre précédent, il suffit de mettre le nom du tableau dynamique comme peramètre
entre les parenthèses lors de l'appel. Ce qui donne:
Code : C++
vector<int> tableau(3,2); //On crée un tableau de 3 entiers
valant 2
fonction(tableau); //On passe le tableau à la fonction
déclarée au-dessus
On ne peut passer un vector<int> que à une fonction recevant un vector<int> et pas à une fonction attendant
un vector<char>. On ne peut pas mélanger les types des éléments stockés !
Si, comme moi, vous aimez découper votre programme en plusieurs fichiers en séparant les fichiers d'en-tête et les fichiers
sources, il faudra penser à ajouter #include <vector> au début du fichier et std:: devant les vector, comme pour
les string en fait:
Code : C++
#ifndef TABLEAU_H_INCLUDED
#define TABLEAU_H_INCLUDED
#include <vector>
void fonctionAvecTableau(std::vector<int>& tableau);
#endif // TABLEAU_H_INCLUDED
Il est tout à fait possible de créer une fonction qui renvoie un vecteur. Je suis certain que vous avez déjà une
idée de comment déclarer une telle fonction. Par exemple, pour une fonction qui retourne un tableau
multidimensionnel de nombres à virgule, la déclaration ressemblerait à ceci :
Code : C++
vector<double> encoreUneFonction(int a)
{
//...
}
Il est important de noter qu'en utilisant cette approche, une copie implicite du tableau sera générée lorsque la
fonction se termine. Pour éviter cette duplication, il est préférable d'opter pour un passage du tableau par
référence, comme nous l'avons précédemment exploré dans le chapitre. Éviter les copies inutiles de tableaux
est essentiel pour maintenir les performances d'un programme. Si vous visez un programme hautement
performant, il est essentiel de prendre en compte la gestion efficace des tableaux.
Les tableaux multi-dimensionnels
Vous pouvez créer des tableaux de divers types de données, tels que des tableaux d'entiers, des tableaux de
chaînes de caractères, et ainsi de suite. De plus, il est possible de créer des tableaux qui contiennent d'autres
tableaux, ce qui peut sembler étrange au premier abord. Pour mieux comprendre ce concept, je vous suggère
de visualiser la mémoire, ce qui peut vous aider à apprécier l'utilité de cette structure de données plutôt
inhabituelle.
Un tableau de tableaux est une structure de données où un tableau principal contient d'autres tableaux
en tant qu'éléments. Chaque tableau interne peut avoir une taille différente, et cela crée une structure de
grille pour organiser les données de manière plus flexible. Cela permet une représentation efficace de
données sous forme de tableau bidimensionnel ou multidimensionnel, ce qui peut être utile dans de
nombreuses applications.

Le terme "tableaux multi-dimensionnels" est utilisé pour mettre en avant le fait que les variables sont organisées
selon plusieurs axes, comme les axes X et Y, plutôt que d'être disposées le long d'un seul axe. Cela permet de
stocker et d'accéder à des données dans un espace à deux dimensions ou plus, offrant une représentation plus
complexe et structurée des données par rapport à un tableau unidimensionnel.
Déclaration d'un tableau multi-dimensionnel
Pour déclarer un tel tableau, il faut indiquer les dimensions les unes après les autres entre crochets :
Code : C++
type nomTableau[tailleX][tailleY]
Donc pour reproduire le tableau du schéma, on doit déclarer le tableau suivant :
Code : C++
int tableau[5][4];
Ou encore mieux, en déclarant des constantes :
Code : C++
int const tailleX(5);
int const tailleY(4);
int tableau[tailleX][tailleY];
Et c'est tout ! C'est bien le C++, non ?
Accéder aux éléments
Pour accéder à une case de notre grille, il faut indiquer la position en X et en Y de la case voulue.
Par exemple tableau[0][0] accède à la case en-bas à gauche de la grille. tableau[0][1] correspond à
celle qui se trouve juste au dessus, alors que tableau[1][0] se situe directement à sa droite.

Comment accéder à la case située en-haut à droite ?


C'est la dernière case dans la direction horizontale, donc entre les premiers crochets, vous devez mettre
"tailleX-1", qui équivaut à 4 dans ce cas. De plus, c'est aussi la dernière case dans la direction verticale. Par
conséquent, entre les seconds crochets, vous devez spécifier "tailleY-1". Ainsi, cela se traduit par
"tableau[4][3]".
Aller plus loin

Il est tout à fait possible d'aller encore plus loin et de créer des grilles tridimensionnelles, voire même des
structures multidimensionnelles plus complexes. Vous pouvez déclarer une variable comme ceci :
Code : C++
double grilleExtreme[5][4][6][2][7];
Bien qu'il soit rare d'avoir besoin de grilles à plus de 3 dimensions dans la programmation courante, les grilles
tridimensionnelles sont couramment utilisées dans des domaines tels que la simulation 3D et la physique pour
représenter des concepts complexes.
De plus, il est possible de créer des tableaux multi-dimensionnels de taille variable en utilisant des vecteurs, ce
qui offre une flexibilité supplémentaire dans la gestion des données.

Code : C++
vector<vector<int> > grille;
Le défi ici est que ce n'est pas strictement un tableau 2D, mais plutôt un tableau de lignes. Par conséquent, la
première étape serait d'ajouter des lignes à notre structure de données avant de pouvoir travailler avec un
tableau 2D complet.
Code : C++
grille.push_back(vector<int>(5)); //On ajoute une ligne de 5
cases à notre grille
grille.push_back(vector<int>(3,4)); //On ajoute une ligne de 3
cases contenant chacune le nombre 4 à notre grille
Chaque ligne peut donc avoir une longueur différente. On peut accéder à une ligne en utilisant les crochets:
Code : C++
grille[0].push_back(8); //Ajoute une case contenant 8 à la
première ligne du tableau
Finalement, on peut accéder aux valeurs dans les cases de la grille en utilisant deux paires de crochets,
comme pour les tableaux statiques. Il faut par contre s 'assurer que cette ligne et cette colonne existent
réellement.
Code : C++
grille[2][3] = 9; //Change la valeur de la cellule (2,3) de la
grille

Les tableaux multi-dimensionnels créés avec des vecteurs ne sont pas la manière la plus efficace d'accéder
à la mémoire et ne sont pas optimisés pour les performances. Par conséquent, il est généralement
préférable d'utiliser des tableaux multi-dimensionnels statiques, à moins que la flexibilité de pouvoir
changer la taille de la grille en cours de route ne soit absolument nécessaire pour votre application.
Les strings comme tableaux
Avant de conclure ce chapitre, il est important de révéler que les chaînes de caractères sont en réalité des
tableaux ! Cette caractéristique est souvent cachée lors de la déclaration, mais en réalité, une chaîne de
caractères est un tableau de lettres. De plus, il existe de nombreuses similitudes avec d'autres types de
tableaux vector dans la façon dont elles sont manipulées en programmation.
Accéder aux lettres
La perspective de considérer une chaîne de caractères comme un tableau de lettres présente l'avantage de
pouvoir accéder à ces lettres et les modifier, ce qui peut être utile. Et comme vous l'avez deviné, l'accès et la
modification des lettres d'une chaîne de caractères s'effectuent également à l'aide de crochets, ce qui facilite
leur manipulation en programmation.
Code : C++
#include <iostream>
#include <string>
using namespace std;
int main()
{
string nomUtilisateur("Julien");
cout << "Vous etes " << nomUtilisateur << "." <<endl;
nomUtilisateur[0] = 'L'; //On modifie la première lettre
nomUtilisateur[2] = 'c'; //On modifie la troisième lettre
cout << "Ah non, vous etes " << nomUtilisateur << "!" << endl;
return 0;
}
Testons pour voir :
Code : Console
Vous etes Julien.
Ah non, vous etes Lucien!
Oui ! Mais on peut faire encore mieux…
Les fonctions
On peut également utiliser size() pour connaître le nombre de lettres et push_back() pour ajouter des lettres
à la fin. La encore, c'est comme avec vector.
Code : C++
string texte("Portez ce whisky au vieux juge blond qui fume.");
//46 caractères
cout << "Cette phrase contient " << texte.size() << " lettres." <<
endl;
Mais contrairement aux tableaux, on peut ajouter plusieurs lettres d'un coup. Et on utilise le +=.
Code : C++
#include <iostream>
#include <string>
using namespace std;
int main()
{
string prenom("Albert");
string nom("Einstein");

string total; //Une chaîne vide


total += prenom; //On ajoute le prénom à
la chaîne vide
total += " "; //Puis un espace
total += nom; //Et finalement le nom
de famille
cout << "Vous vous appelez " << total <<
"." << endl;
return 0;
}
Cela donne bien sûr :
Code : Console
Vous vous appelez Albert Einstein.
En résumé
Les tableaux sont des successions de variables en mémoire. Un tableau à 4 cases correspond donc en
mémoire à 4 variables les unes à la suite des autres. Un tableau s 'initialise comme ceci : int
meilleurScore[4]; (pour 4 cases).
La première case est toujours numérotée 0 (meilleurScore[0]).
Si la taille du tableau est susceptible de varier, créez un tableau dynamique de type vector : vector<int>
tableau(5);.
On peut créer des tableaux multi-dimensionnels. Par exemple, int tableau[5][4]; revient à créer un
tableau de 5 lignes et 4 colonnes.
Les chaînes de caractères string peuvent être considérées comme des tableaux. Chacune des cases
correspond à un caractère.
Lire et modifier des fichiers
Dans l'apprentissage du C++, nous avons couvert les bases, mais il est maintenant essentiel d'aborder
l'interaction avec les fichiers. Jusqu'à présent, nous nous sommes concentrés sur la console et la saisie
utilisateur, ce qui est loin d'être suffisant.
Les logiciels que nous utilisons au quotidien, tels que les éditeurs de texte, les environnements de
développement, et même les jeux vidéo, doivent tous être capables de lire et d'écrire dans des fichiers.
Cette compétence est donc cruciale pour développer des applications plus avancées. Heureusement, si
vous maîtrisez déjà les concepts de "cin" et "cout", vous avez déjà une bonne base pour apprendre à
interagir avec les fichiers en C++.

Écrire dans un fichier


Lorsque vous travaillez avec des fichiers en C++, la première étape est de les ouvrir, similaire à l'utilisation
de "cin" et "cout". Vous utilisez des opérateurs comme "<<" et ">>" pour interagir avec les fichiers. Ces
connexions entre le programme et les fichiers sont appelées des "flux". Dans ce chapitre, nous allons
explorer la lecture et la modification de fichiers en utilisant ces flux. En termes plus simples, nous allons
apprendre à manipuler des fichiers.

L'en-tête fstream
Comme c'est courant en C++, lorsque vous avez besoin d'une fonctionnalité particulière, vous devez
commencer par inclure le bon fichier d'en-tête. Dans le cas des fichiers, vous devez ajouter "#include
<fstream>" en haut de votre code source pour pouvoir utiliser les fonctionnalités liées à la manipulation de
fichiers.
Vous êtes déjà familier avec "iostream," qui contient les outils nécessaires pour les entrées/sorties vers la console.
"iostream" signifie en réalité "input/output stream," ce qui se traduit par "flux d'entrées/sorties" en français. En
revanche, "fstream" signifie "file stream," c'est-à-dire "flux vers les fichiers" en français. C'est donc avec "fstream"
que vous travaillerez pour la manipulation de fichiers.

La principale différence réside dans le fait qu'il vous faut un flux distinct pour chaque fichier. Explorons
maintenant la création d'un flux sortant, c'est-à-dire un flux qui vous permet d'écrire dans un fichier.
Ouvrir un fichier en écriture
Il est important de comprendre que les flux sont en réalité des objets, ce qui est cohérent avec le fait que le
C++ est un langage orienté objet. Considérez-les pour l'instant comme de grandes variables améliorées.

Ces objets contiennent une multitude d'informations sur les fichiers ouverts et offrent des fonctionnalités
telles que la fermeture du fichier, le retour au début, et bien d'autres encore.
L'aspect crucial pour nous est que la déclaration d'un flux suit la même syntaxe qu'une variable, avec le type
"ofstream" pour les flux sortants, et le chemin d'accès du fichier que vous souhaitez manipuler comme valeur.
Tout comme pour les variables, il existe quelques règles à respecter pour nommer un flux : les noms de flux
sont composés de lettres, de chiffres et du tiret bas "_" uniquement ; le premier caractère doit être une lettre
(majuscule ou minuscule) ; les accents ne sont pas autorisés, et les espaces ne peuvent pas être utilisés dans
le nom du flux.
Vous avez certainement remarqué que ces règles sont exactement les mêmes que celles que nous appliquons
aux variables. Par conséquent, je ne vais pas répéter les règles que nous avons déjà abordées au chapitre 4, et
qui sont largement adoptées par les programmeurs. Dans la suite de ce chapitre, nous utiliserons le nom
"monFlux" comme exemple de nom pour les flux. Ce nom respecte tous les critères, et j'espère que vous serez
d'accord pour l'utiliser.
include <iostream>
#include <fstream>
using namespace std;
int main()
Code
{ : C++
ofstream monFlux("C:/Nanoc/scores.txt");
//Déclaration d'un flux permettant
d'écrire dans le fichier
// C:/Nanoc/scores.txt
return 0;
}
Le chemin d'accès au fichier doit être spécifié entre guillemets et peut prendre l'une des deux formes suivantes
: un chemin absolu, qui part de la racine du disque, ou un chemin relatif, qui est défini par rapport au répertoire
où se trouve le programme.
C:/benabdallah/C++/Fichiers/scores.txt.
Un chemin relatif indique l'emplacement d'un fichier par rapport à l'emplacement du programme sur le disque.
Par exemple :Fichiers/scores.txt si mon programme se situe dans le dossier C:/benabdallah/C++/.
À partir de là, on peut utiliser le flux pour écrire dans le fichier.
Si le fichier n'existe pas, le programme le créera automatiquement. Cependant, il est important que le dossier dans lequel
vous essayez de créer le fichier existe déjà. Dans l'exemple précédent, le dossier "C:/benabdallah/C++/Fichiers" doit
déjà exister. Si ce dossier n'existe pas, rien ne sera écrit.
Le plus souvent, le nom du fichier est contenu dans une chaîne de caractères string. Dans ce cas, il faut
utiliser la fonction c_str() lors de l'ouverture du fichier.
Code : C++
string const nomFichier("C:/Nanoc/scores.txt");
ofstream monFlux(nomFichier.c_str());
//Déclaration d'un flux permettant d'écrire dans un fichier.
Des problèmes peuvent survenir lors de l'ouverture d'un fichier, si le fichier ne vous appartient pas ou si le
disque dur est plein par exemple. C'est pour cela qu'il faut toujours tester si tout s 'est bien passé. On utilise
pour cela la syntaxe if(monFlux). Si ce test n'est pas vrai, alors c'est qu'il y a eu un problème et que l'on ne
peut pas utiliser le fichier.
Code : C++
ofstream monFlux("C:/Nanoc/scores.txt"); //On essaye d'ouvrir le
fichier
if(monFlux) //On teste si tout est OK
{
//Tout est OK, on peut utiliser le fichier
}
else
{
cout << "ERREUR: Impossible d'ouvrir le fichier." << endl;
}
Tout est donc prêt pour commencer l'écriture dans le fichier. Vous verrez que cela ne diffère pas
fondamentalement de ce que vous avez déjà appris.
Écrire dans un flux
Je vous avais dit que tout était comme pour cout. C'est donc sans surprise que je vous présente le moyen
d'envoyer des informations dans un flux : ce sont les chevrons (<<) qu'il faut utiliser.
Code : C++
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
string const nomFichier("C:/Nanoc/scores.txt");
ofstream monFlux(nomFichier.c_str());
if(monFlux)
{
monFlux << "Bonjour, je suis une phrase écrite dans un
fichier." << endl;
monFlux << 42.1337 << endl;
int age(23);
monFlux << "J'ai " << age << " ans." << endl;
}
else
{
cout << "ERREUR: Impossible d'ouvrir le fichier." << endl;
}
return 0;
}

En exécutant ce programme, vous obtiendrez un fichier nommé "scores.txt" sur votre disque, et voici le
contenu de ce fichier :

Je vous encourage à créer un programme qui sollicite l'utilisateur pour son nom et son âge, puis enregistre
ces informations dans un fichier.
Les différents modes d'ouverture
Il ne nous reste plus qu'un petit point à régler.
Que se passe-t-il si le fichier existe déjà ?

Il sera supprimé et remplacé par ce que vous écrivez, ce qui est problématique si l'on souhaite ajouter des
informations à la fin d'un fichier pré-existant.
Pensez par exemple à un fichier qui contiendrait la liste des actions effectuées par l'utilisateur : on ne veut pas
tout effacer à chaque fois, on veut juste y ajouter des lignes.
Pour pouvoir écrire à la fin d'un fichier, il faut le spécifier lors de l'ouverture en ajoutant un deuxième paramètre à
la création du flux : ofstream monFlux("C:/benabdallah/scores.txt", ios::app);.

app est un raccourci pour append, le verbe anglais qui signifie « ajouter à la fin ».

En utilisant ce mode d'ouverture, vous n'aurez plus à vous soucier de l'écrasement des données existantes.
Tout ce que vous écrirez sera ajouté à la fin du fichier sans effacer son contenu précédent.
Lire un fichier
Nous avons abordé l'écriture dans un fichier, explorons maintenant la lecture d'un fichier. Vous constaterez
que cela ne diffère pas beaucoup de ce que vous connaissez déjà.
Ouvrir un fichier en lecture…
Le principe est exactement le même : on va simplement utiliser un ifstream au lieu d'un ofstream. Il faut
également tester l'ouverture, afin d'éviter les erreurs.
Code : C++
ifstream monFlux("C:/Nanoc/C++/data.txt"); //Ouverture d'un fichier
en lecture
if(monFlux)
{
//Tout est prêt pour la lecture.
}
else
{
cout << "ERREUR: Impossible d'ouvrir le fichier en lecture." <<
endl;
}
Rien de bien nouveau. … et le lire
Il y a trois manières différentes de lire un fichier :
1. Ligne par ligne, en utilisant getline() ;
2. Mot par mot, en utilisant les chevrons >> ;
3. Caractère par caractère, en utilisant get().
Voyons ces trois méthodes en détail.
Lire ligne par ligne
La première méthode permet de récupérer une ligne entière et de la stocker dans une chaîne de caractères.
Code : C++
string ligne;
getline(monFlux, ligne); //On lit une ligne complète
Le fonctionnement est exactement le même qu'avec cin. Vous savez donc déjà tout.
Lire mot par mot
La deuxième manière de faire, vous la connaissez aussi. Comme je suis gentil, je vous propose quand même un
petit rappel.
Code : C++
double nombre;
monFlux >> nombre; //Lit un nombre à virgule depuis le fichier
string mot;
monFlux >> mot; //Lit un mot depuis le fichier
Cette méthode lit ce qui se trouve entre l'endroit où l'on se situe dans le fichier et l'espace suivant. Ce qui est lu
est alors traduit en double, int ou string selon le type de variable dans lequel on écrit.
Lire caractère par caractère
Finalement, il nous reste la dernière méthode, la seule réellement nouvelle. Mais elle est tout aussi simple, je
vous rassure.
Code : C++
char a;
monFlux.get(a);
Ce code lit une seule lettre et la stocke dans la variable a.

Cette méthode lit réellement tous les caractères. Les espaces, retours à la ligne et tabulations sont, entre autres, lus par
cette fonction. Bien que bizarres, ces caractères seront néanmoins stockés dans la variable.

Souvenez-vous de ce que nous avions vu au chapitre 5 lorsque nous avons découvert l'utilisation de cin.
Nous avions appris qu'il fallait utiliser cin.ignore() lorsque l'on passait de la lecture mot par mot à la
lecture ligne par ligne. Il en va de même ici. Il faudra donc écrire:
Code : C++
ifstream monFlux("C:/Nanoc/C++/data.txt");
string mot;
monFlux >> mot; //On lit un mot depuis le fichier
monFlux.ignore(); //On change de mode
string ligne;
getline(monFlux, ligne); //On lit une ligne complète
Mais je vous avouerai que ce n'est pas souvent que l'on change de mode de lecture en cours de route.
Lire un fichier en entier
Pour savoir si nous pouvons continuer à lire un fichier, nous utilisons la valeur renvoyée par la fonction
"getline()". Si elle renvoie "true", nous pouvons continuer la lecture, sinon, c'est que nous avons atteint la fin
du fichier ou qu'une erreur s'est produite, et nous devons nous arrêter. Pour cela, nous utilisons généralement
une boucle "while".
Code : C++
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
ifstream fichier("C:/Nanoc/fichier.txt");
if(fichier)
{
//L'ouverture s'est bien passée, on peut donc lire
string ligne; //Une variable pour stocker les lignes lues
while(getline(fichier, ligne)) //Tant qu'on n'est pas à la
fin, on lit
{
cout << ligne << endl;
//Et on l'affiche dans la console
//Ou alors on fait quelque chose avec cette ligne
//À vous de voir
}
}
else
{
cout << "ERREUR: Impossible d'ouvrir le fichier en lecture."
<< endl;
}
return 0;
}
Une fois les lignes du fichier lues, elles peuvent être manipulées selon les besoins. Dans cet exemple, nous les
affichons simplement, mais en pratique, elles peuvent être utilisées de manière variée en fonction de votre
programme. C'est la méthode standard pour lire un fichier, et une fois que les lignes sont stockées dans une
variable de type "string", elles peuvent être traitées à l'aide des opérations courantes sur les chaînes de
caractères.
Quelques astuces
Fermer prématurément un fichier
Je vous ai expliqué en tout début de chapitre comment ouvrir un fichier. Mais je ne vous ai pas montré
comment le refermer. Ce n'est pas un oubli de ma part, il s 'avère juste que ce n'est pas nécessaire. Les fichiers
ouverts sont automatiquement refermés lorsque l'on sort du bloc où le flux est déclaré.
Code : C++
void f()
{
ofstream flux("C:/benabdallah/data.txt"); //Le fichier est ouvert
//Utilisation du fichier} //Lorsque l'on sort du bloc, le fichier est
automatiquement refermé
Il n'y a donc rien à faire. Aucun risque d'oublier de refermer le fichier ouvert. Il arrive par contre qu'on ait besoin
de fermer le fichier avant sa fermeture automatique. Il faut alors utiliser la fonction close() des flux.
Code : C++
void f()
{
ofstream flux("C:/Nanoc/data.txt"); //Le fichier est ouvert
//Utilisation du fichier
flux.close(); //On referme le fichier
//On ne peut plus écrire dans le fichier à partir
d'ici
}
De la même manière, il est possible de retarder l'ouverture d'un fichier après la déclaration du flux en utilisant la
fonction
open().
Code : C++
void f()
{
ofstream flux; //Un flux sans fichier associé
flux.open("C:/benabdallah/data.txt"); //On ouvre le fichier
C:/Nanoc/data.txt
//Utilisation du fichier
flux.close(); //On referme le fichier
//On ne peut plus écrire dans le fichier à partir d'ici
}
Comme vous pouvez le constater, c'est un processus simple. Cependant, dans la plupart des situations, cette
étape est inutile. Il est généralement suffisant d'ouvrir directement le fichier et de le laisser se fermer
automatiquement lorsque cela est nécessaire.
Il y a des personnes qui aiment utiliser les fonctions "open()" et "close()" pour mieux visualiser où le fichier est ouvert
et fermé. Cependant, ce n'est pas nécessaire car les fichiers se ferment automatiquement lorsque le flux sort de portée.
C'est une question de préférence personnelle.
Le curseur dans le fichier
Voyons de plus près comment se déroule la lecture d'un fichier. Lorsque vous ouvrez un fichier dans un
éditeur de texte, comme le Bloc-notes, un curseur indique l'endroit où vous allez écrire.

Lorsque l'on tape une lettre sur le clavier dans un éditeur de texte, cette lettre est ajoutée à l'emplacement du
curseur dans le fichier. Cela ne devrait pas être surprenant. Ce qui est intéressant, c'est qu'en C++, il existe
également une sorte de curseur. Lorsque vous utilisez la ligne de code suivante :
Code : C++
ifstream fichier("C:/Nanoc/scores.txt")
le fichier C:/Nanoc/scores.txt est ouvert et le curseur est placé tout au début du fichier. Si on lit le premier
mot du fichier, on obtient bien sûr la chaîne de caractères « Nanoc » puisque c'est le premier mot du fichier. Ce
faisant, le « curseur C++ » se déplace jusqu'au début du mot suivant, comme à la figure suivante.
Le mot suivant qui peut être lu est donc « : », puis « 118218 », et ainsi de suite jusqu'à la fin. On est donc obligé
de lire un fichier dans l'ordre. Ce n'est pas très pratique. Heureusement, il existe des moyens de se déplacer
dans un fichier. On peut par exemple dire « je veux placer le curseur 20 caractères après le début » ou « je veux
avancer le curseur de 32 caractères ». On peut ainsi lire uniquement les parties qui nous intéressent réellement.
La première chose à faire est de savoir où se situe le curseur. Dans un deuxième temps, on pourra le déplacer.
Connaître sa position
Il existe une fonction permettant de savoir à quel octet du fichier on se trouve. Autrement dit, elle permet de
savoir à quel caractère du fichier on se situe. Malheureusement, cette fonction n'a pas le même nom pour les
flux entrant et sortant et, en plus, ce sont des noms bizarres. Je vous ai mis les noms des deux fonctions dans
un petit tableau

Pour ifstream Pour ofstream

tellg() tellp()
Cependant, malgré leurs noms différents, ces deux fonctions s'utilisent de la même manière.
Code : C++
ofstream fichier("C:/Nanoc/data.txt");
int position = fichier.tellp(); //On récupére la position
cout << "Nous nous situons au " << position << "eme caractere du
fichier." << endl;
Se déplacer
Là encore, il existe deux fonctions, une pour chaque type de flux.

Pour ifstream Pour ofstream

seekg() seekp()

Ces deux fonctions s'utilisent de la même manière, donc je vais vous présenter une seule version. Elles
prennent deux arguments : une position dans le fichier et un nombre de caractères à ajouter à cette position :
Code : C++
flux.seekp(nombreCaracteres, position);
Les trois positions possibles sont :
le début du fichier : ios::beg ;
la fin du fichier : ios::end ;
la position actuelle : ios::cur.
Par exemple, si je veux me positionner 10 caractères après le début du fichier, j'utilise :flux.seekp(10,
ios::beg);. Si je veux avancer de 20 caractères à partir de la position actuelle du curseur, j'utilise
:flux.seekp(20, ios::cur);.
Connaître la taille d'un fichier
La troisième astuce pour connaître la taille d'un fichier combine en réalité les deux astuces précédentes. Pour
obtenir la taille du fichier, nous nous déplaçons vers la fin du fichier en utilisant la fonction de
positionnement, puis nous demandons au flux de nous indiquer où il se trouve. Vous voyez comment cela
fonctionne ?
Code : C++
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ifstream fichier("C:/Nanoc/meilleursScores.txt"); //On ouvre le
fichier
fichier.seekg(0, ios::end); //On se déplace à la fin du
Fichier
int taille;
taille = fichier.tellg();
//On récupère la position qui correspond donc a la taille du
fichier !
cout << "Taille du fichier : " << taille << " octets." << endl;
return 0;
}
En résumé
En C++, pour lire ou écrire dans un fichier, on doit inclure le fichier d'en-tête <fstream>.
On doit créer un objet de type ofstream pour ouvrir un fichier en écriture et ifstream pour l'ouvrir en
lecture.
L'écriture se fait comme avec cout : monFlux << "Texte"; tandis que la lecture se fait comme avec cin :
monFlux >> variable;.
On peut lire un fichier ligne par ligne avec getline().
Le curseur indique à quelle position vous êtes au sein du fichier, pendant une opération de lecture ou
d'écriture. Au besoin, il est possible de déplacer ce curseur.
Projet : le mot mystère
Depuis le début de ce cours sur le C++, vous avez acquis de nombreuses notions telles que le compilateur,
l'IDE, les variables, les fonctions, les conditions et les boucles. Vous avez pu voir des exemples d'utilisation de
ces notions au fur et à mesure de votre apprentissage. Cependant, avez-vous déjà pris le temps de créer un
véritable programme pour vous entraîner ? Si ce n'est pas le cas, c'est le moment de le faire ! Dans ce cours,
vous trouverez régulièrement des travaux pratiques (TP) pour vous permettre de vous lancer réellement dans
la programmation. Ce projet en particulier n'est pas très complexe, mais il promet d'être amusant. Vous allez
mélanger les lettres d'un mot et demander à un joueur de retrouver le mot « mystère » qui se cache derrière
ces lettres.

Préparatifs et conseils
Le jeu que nous allons créer consiste à deviner un mot dont les lettres ont été mélangées. Bien que cela
puisse sembler simple, nous aurons besoin d'appliquer les notions que nous avons apprises au cours des
chapitres précédents pour le réaliser.
les variables string ;
Pour réussir ce projet, nous aurons besoin d'utiliser les concepts que nous avons appris jusqu'à présent,
notamment les fonctions et les structures de contrôle comme les boucles et les conditions.
Principe du jeu « Le mot mystère »
Nous voulons réaliser un jeu qui se déroule de la façon suivante :
1. Le joueur 1 saisit un mot au clavier ;
2. L'ordinateur mélange les lettres du mot ;
3. Le joueur 2 essaie de deviner le mot d'origine à partir des lettres mélangées.
Voici un exemple de partie du jeu que nous allons réaliser :
Code : Console
Saisissez un mot
MYSTERE
Quel est ce mot ? MSERETY
RESEMTY
Ce n'est pas le mot !
Quel est ce mot ? MSERETY
MYRESTE
Ce n'est pas le mot !
Quel est ce mot ? MSERETY
MYSTERE
Bravo !
1. Dans cette partie, le joueur 1 choisit « MYSTERE » comme mot à deviner.
2. L'ordinateur mélange les lettres et demande au joueur 2 de retrouver le mot qui se cache derrière « MSERETY
».
Le joueur 2 essaie de trouver le mot. Ici, il y parvient au bout de 3 essais :
1. RESEMTY : on lui dit que ce n'est pas cela
2. MYRESTE : là non plus
3. MYSTERE : là on lui dit bravo car il a trouvé, et le programme s 'arrête.
Bien sûr, en l'état, le joueur 2 peut facilement lire le mot saisi par le joueur 1. Nous verrons à la fin du TP
comment nous pouvons améliorer cela.
Quelques conseils pour bien démarrer
Quand on lâche un débutant dans la nature la première fois, avec comme seule instruction « Allez, code-moi
cela », il est en
général assez désemparé.
« Par quoi dois-je commencer ? », « Qu'est-ce que je dois faire, qu'est-ce que je dois utiliser ? ». Bref, il ne sait
pas du tout comment s 'y prendre et c'est bien normal vu qu'il n'a jamais fait cela.
Mais moi, je n'ai pas envie que vous vous perdiez ! Je vais donc vous donner une série de conseils pour que
vous soyez préparés au mieux. Bien entendu, ce sont juste des conseils, vous en faites ce que vous voulez.
Repérez les étapes du programme
Je vous ai décrit un peu plus tôt les 3 étapes du programme :
1. Saisie du mot à deviner ;
2. Mélange des lettres ;
3. Boucle qui se répète tant que le mot mystère n'a pas été trouvé.
Ces étapes sont en fait assez indépendantes. Plutôt que d'essayer de réaliser tout le programme d'un coup,
pourquoi
n'essayeriez-vous pas de faire chaque étape indépendamment des autres ?
1. L'étape 1 est très simple : l'utilisateur doit saisir un mot qu'on va stocker en mémoire (dans une variable de
type string, car c'est le type adapté). Si vous connaissez cout et cin, vous ne mettrez pas plus de quelques
minutes à écrire le code correspondant.
2. L'étape 2 est la plus complexe : vous avez un string qui contient un mot comme « MYSTERE » et vous
voulez aléatoirement mélanger les lettres pour obtenir quelque chose comme « MSERETY ». Comment faire
? Je vais vous aider un peu pour cela car vous devez utiliser certaines choses que nous n'avons pas vues.
3. L'étape 3 est de difficulté moyenne : vous devez créer une boucle qui demande de saisir un mot et qui le
compare au mot mystère. La boucle s 'arrête dès que le mot saisi est identique au mot mystère.
Créez un canevas de code avec les étapes
Comme vous le savez, tous les programmes contiennent une fonction main(). Écrivez dès maintenant des
commentaires pour séparer les principales étapes du programme. Cela devrait donner quelque chose de
comparable au squelette ci-dessous :
Code : C++
int main()
{
//1 : On demande de saisir un mot
//2 : On mélange les lettres du mot
//3 : On demande à l'utilisateur quel est le mot mystère
return 0;
}
À vous de réaliser les étapes ! Pour y aller en difficulté croissante, je vous conseille de faire
d'abord l'étape 1, puis l'étape 3 et enfin l'étape 2.
Une fois que vous aurez terminé les étapes 1 et 3, le programme vous demandera de saisir un mot à
nouveau. Cela peut sembler un peu répétitif, mais c'est une étape importante pour valider les premières
parties du TP. Alors, n'hésitez pas à avancer étape par étape !
Voici un aperçu du programme "intermédiaire" avec seulement les étapes 1 et 3 réalisées :
Code : Console
Saisissez un mot
MYSTERE
Quel est ce mot ?
RESEMTY
Ce n'est pas le mot !
Quel est ce mot ?
MYRESTE
Ce n'est pas le mot !
Quel est ce mot ?
MYSTERE
Bravo !
Comme vous pouvez le constater, dans la version "intermédiaire" du programme, le mot avec les lettres
mélangées n'est pas encore généré. Cependant, si vous parvenez à réaliser cette partie, vous aurez déjà
accompli 50% du travail !
Un peu d'aide pour mélanger les lettres
L'étape de mélange des lettres est probablement la partie la plus complexe de ce TP. Cependant, je vais vous
fournir quelques informations et conseils pour vous aider à la réaliser avec succès.
Tirer un nombre au hasard
Pour mélanger les lettres de manière aléatoire, vous devrez utiliser des nombres aléatoires. Voici comment
procéder :
• Au début de votre code, assurez-vous d'inclure les bibliothèques "ctime" et "cstdlib" pour avoir accès aux
fonctionnalités de génération de nombres aléatoires.
• Vous devrez appeler la fonction "srand(time(0));" une seule fois au début de votre programme, généralement
dans la fonction "main()", pour initialiser la génération de nombres aléatoires.
• Pour générer un nombre aléatoire compris entre 0 et 4 (par exemple), utilisez l'expression suivante
:nbAleatoire = rand() % 5;". Il est important de noter que nous utilisons "5" pour obtenir un nombre entre 0 et
4.
• Voici un exemple de code qui génère un nombre aléatoire entre 0 et 4 :
Code : C++
#include <iostream>
#include <ctime> // Obligatoire
#include <cstdlib> // Obligatoire
using namespace std;
int main()
{
int nbAleatoire(0);
srand(time(0));
nbAleatoire = rand() % 5;
return 0;
Tirer une lettre au hasard
}
Tirer un nombre au hasard c'est bien mais, pour ce programme, j'ai besoin de tirer une lettre au hasard pour
mélanger les lettres !

Imaginons que vous ayez un string appelé motMystere qui contient le mot « MYSTERE ». Vous avez appris
que les string pouvaient être considérés comme des tableaux, souvenez-vous ! Ainsi, motMystere[0]
correspond à la première lettre, motMystere[1] à la deuxième lettre, etc. Il suffit de générer un nombre
aléatoire entre 0 et le nombre de lettres du mot (qui nous est donné par motMystere.size()) pour tirer une
lettre au hasard ! Une petite idée de code pour récupérer une lettre au hasard :
Code : C++
#include <iostream>
#include <string>
#include <ctime>
#include <cstdlib>
using namespace std;
int main()
{
string motMystere("MYSTERE");

srand(time(0));

int position = rand() % motMystere.size();

cout << "Lettre au hasard :" << motMystere[position];


return 0;
Retirer une lettre d'un string
Pour éviter de tirer 2 fois la même lettre d'un mot, je vous conseille de retirer au fur et à mesure les lettres qui
ont été piochées. Pour ce faire, on va faire appel à erase() sur le mot mystère, comme ceci :
Code : C++
motMystere.erase(4, 1); // Retire la lettre n°5
Il y a 2 paramètres :
le numéro de la lettre à retirer du mot (ici 4, ce qui correspond à la 5ème lettre car on commence à compter à
partir de 0) ;
le nombre de lettres à retirer (ici 1).
Créez des fonctions !
Ce n'est pas une obligation mais, plutôt que de tout mettre dans le main(), vous pourriez créer des fonctions
qui ont des rôles spécifiques. Par exemple, l'étape 2 qui génère un mot dont les lettres ont été mélangées
mériterait d'être fournie sous forme de onction. Ainsi, on pourrait appeler la fonction comme ceci dans le
main() :
Code : C++
motMelange = melangerLettres(motMystere);
On lui envoie le motMystere, elle nous renvoie un motMelange.
Bien entendu, toute la difficulté consiste ensuite à coder cette fonction melangerLettres. Allez, au boulot !
Les pointeurs
Dans ce chapitre, nous allons aborder un sujet plus avancé : les pointeurs. Les pointeurs sont des éléments
fondamentaux en programmation C++. Bien qu'ils puissent sembler complexes au début, ils sont essentiels
pour comprendre le fonctionnement interne de la mémoire de l'ordinateur et maîtriser certaines fonctionnalités
avancées du langage. Ne vous inquiétez pas si vous ne comprenez pas tout du premier coup, c'est normal.
Vous pouvez relire ce chapitre à plusieurs reprises pour bien assimiler ces concepts.

Une question d'adresse

Dans le chapitre précédent, nous avons étudié la mémoire et comment les variables y sont stockées. Lorsque
nous déclarons une variable, l'ordinateur alloue de l'espace mémoire pour cette variable et lui attribue un nom.

Code : C++
int main()
{
int ageUtilisateur(16);
return 0;
}
Nous pouvons représenter la mémoire utilisée dans ce programme avec un schéma similaire à celui de la
figure suivante.
Dans un ordinateur, la mémoire est composée de « cases » individuelles, et chacune de ces cases a une
adresse unique, comme illustré dans la figure suivante.
Dans le schéma, nous pouvons voir toutes les cases de la mémoire avec leurs adresses. Notre programme
utilise une seule de ces cases, la case 53768, pour stocker sa variable.

On ne peut pas mettre deux variables dans la même case.

Chaque variable possède une adresse unique, et chaque adresse correspond à une seule variable. L'adresse est
un autre moyen d'accéder à une variable. On peut atteindre une variable en utilisant son nom (l'étiquette) ou son
adresse (son numéro de case). Par exemple, on peut dire à l'ordinateur "Affiche moi le contenu de l'adresse
53768" ou "Additionne les contenus des adresses 1267 et 91238". Mais pourquoi utiliser les adresses alors que
l'utilisation des noms est simple et efficace ? Nous verrons plus tard dans ce chapitre que l'accès aux adresses
peut être nécessaire, mais commençons par voir comment obtenir l'adresse d'une variable.
Afficher l'adresse
En C++, pour obtenir l'adresse d'une variable, on utilise le symbole de l'esperluette (&). Par exemple, si nous
voulons obtenir l'adresse de la variable "ageUtilisateur", nous écrivons "&ageUtilisateur". Voyons comment
cela fonctionne.
Code : C++
#include <iostream>
using namespace std;
int main()
{
int ageUtilisateur(16);
cout << "L'adresse est : " << &ageUtilisateur << endl;
//Affichage de l'adresse de la variable
return 0;
}
Chez moi, j'obtiens le résultat suivant :
Code : Console
L'adresse est : 0x22ff1c

Vous aurez certainement un résultat différent. La case peut changer d'une exécution à l'autre du programme.

Il est important de noter que l'adresse mémoire d'une variable peut varier d'une exécution du programme à
l'autre. Chaque fois que vous exécutez le programme, il peut être chargé dans une zone différente de la
mémoire, ce qui entraîne un changement d'adresse pour les variables. Il n'est donc pas nécessaire de
mémoriser ces adresses, car elles peuvent varier d'une exécution à l'autre.
L'esperluette (&) en C++ est utilisée pour obtenir l'adresse mémoire d'une variable, mais dans la plupart des
cas, afficher directement cette adresse n'est pas nécessaire pour les tâches courantes.

L'esperluette (&) est utilisée à la fois pour obtenir l'adresse mémoire d'une variable et pour déclarer des références en
C++. Il est important de faire la distinction entre ces deux utilisations pour éviter toute confusion.

Explorons les actions que l'on peut entreprendre avec les adresses des variables en C++.
Les pointeurs
Les adresses sont des nombres. Vous connaissez plusieurs types permettant de stocker des nombres : int,
unsigned int, double. Un pointeur en C++ est une variable qui stocke l'adresse mémoire d'une autre
variable. C'est essentiel pour comprendre la manipulation des pointeurs.
Déclarer un pointeur
Pour déclarer un pointeur en C++, vous devez spécifier le type de la variable dont vous souhaitez stocker
l'adresse, suivi d'une étoile (*), et enfin, vous donnez un nom au pointeur.
Code : C++
int *pointeur;
Ce code déclare un pointeur qui peut contenir l'adresse d'une variable de type int.
On peut également écrire int* pointeur (avec l'étoile collée au mot int).
Cette notation a un léger inconvénient, c'est qu'elle ne permet pas de déclarer plusieurs pointeurs sur la même ligne,
comme ceci : int* pointeur1, pointeur2, pointeur3;. Si l'on procède ainsi, seul pointeur1 sera un
pointeur, les deux autres variables seront des entiers tout à fait standard.
On peut bien sûr faire cela pour n'importe quel type :
Code : C++
double *pointeurA;
//Un pointeur qui peut contenir l'adresse d'un nombre à virgule
unsigned int *pointeurB;
//Un pointeur qui peut contenir l'adresse d'un nombre entier
positif
string *pointeurC;
//Un pointeur qui peut contenir l'adresse d'une chaîne de
Caractères
vector<int> *pointeurD;
//Un pointeur qui peut contenir l'adresse d'un tableau dynamique de
nombres entiers
int const *pointeurE;
//Un pointeur qui peut contenir l'adresse d'un nombre entier
constant
En C++, il est crucial d'initialiser un pointeur en lui attribuant une adresse dès sa déclaration pour éviter des
comportements indésirables. Une valeur initiale couramment utilisée est 0, ce qui indique que le pointeur ne
pointe vers aucune adresse mémoire en particulier.

Code : C++
int *pointeur(0);
double *pointeurA(0);
unsigned int *pointeurB(0);
string *pointeurC(0);
vector<int> *pointeurD(0);
int const *pointeurE(0);

Effectivement, sur le schéma que j'ai présenté précédemment, la première case de la mémoire avait l'adresse 1.
L'adresse 0 n'existe pas. Donc, lorsque vous créez un pointeur contenant l'adresse 0, cela signifie qu'il ne
contient l'adresse d'aucune case mémoire.

Déclarez toujours vos pointeurs en les initialisant à l'adresse 0.


Stocker une adresse
Maintenant qu'on a la variable, il n'y a plus qu'à y mettre une valeur. Vous savez déjà comment obtenir
l'adresse d'une variable (rappelez-vous du &). Allons-y !
Code : C++
int main()
{
int ageUtilisateur(16);
//Une variable de type int
int *ptr(0);
//Un pointeur pouvant contenir l'adresse d'un nombre entier
ptr = &ageUtilisateur;
//On met l'adresse de 'ageUtilisateur' dans le pointeur 'ptr'
return 0;
}
La ligne ptr = &ageUtilisateur; est celle qui nous intéresse. Elle écrit l'adresse de la variable
ageUtilisateur dans le pointeur ptr. On dit alors que le pointeur ptr pointe sur ageUtilisateur.
Voyons comment tout cela se déroule dans la mémoire grâce à un schéma (figure suivante) !
Dans cette illustration, nous avons une représentation familière de la mémoire, avec ses cases numérotées,
contenant la variable ageUtilisateur dans la case n°53768. Cependant, la nouveauté réside dans l'introduction
d'un pointeur. Dans la case mémoire n°14566, nous avons une variable appelée "ptr" qui stocke l'adresse
53768, c'est-à-dire l'adresse de la variable ageUtilisateur.

Bien que cela puisse sembler étrange à première vue (pourquoi stocker l'adresse d'une variable dans une
autre case ?), cela deviendra progressivement plus clair à mesure que nous explorerons davantage ce
concept. Une fois que vous avez compris ce schéma, vous serez prêt à aborder des programmes plus
complexes impliquant des pointeurs.
Afficher l'adresse
Comme pour toutes les variables, on peut afficher le contenu d'un pointeur.
Code : C++
#include <iostream>
using namespace std;
int main()
{
int ageUtilisateur(16);
int *ptr(0);
ptr = &ageUtilisateur;
cout << "L'adresse de 'ageUtilisateur' est : " <<
&ageUtilisateur << endl;
cout << "La valeur de pointeur est : " << ptr << endl;
return 0;
}
Cela donne :
return 0;
}
Code : Console
L'adresse de 'ageUtilisateur' est : 0x2ff18
La valeur de pointeur est : 0x2ff18
La valeur du pointeur est donc bien l'adresse de la variable pointée. On a bien réussi à stocker une adresse !
Accéder à la valeur pointée
Les pointeurs jouent un rôle crucial : ils permettent d'accéder à une variable sans avoir besoin de son nom.
Pour ce faire, il suffit d'utiliser l'opérateur d'étoile (*) devant le pointeur pour afficher la valeur de la variable
pointée.

Code : C++
int main()
{
int ageUtilisateur(16);
int *ptr(0);
ptr= &ageUtilisateur;

cout << "La valeur est : " << *ptr << endl;
return 0;
}
En utilisant cout << *ptr, le programme suit ces étapes :

Accéder à la case mémoire nommée ptr.


Lire la valeur enregistrée dans ptr.
"Suivre la flèche" pour accéder à l'adresse pointée par ptr.
Lire la valeur stockée dans cette adresse.
Afficher cette valeur, qui dans ce cas est 16.
En utilisant l'opérateur d'étoile (*), on accède à la valeur de la variable pointée. Cela s'appelle la
"déréférenciation" d'un pointeur. C'est un deuxième moyen d'accéder à la valeur de ageUtilisateur.
Mais à quoi cela sert-il ?

Vous avez peut-être été intrigués par cette notion, mais la réponse à son utilité viendra plus tard
dans ce chapitre. Pour tout comprendre, il est nécessaire de poursuivre la lecture jusqu'à la fin.
Récapitulatif de la notation
Pour récapituler, voici les points essentiels à retenir concernant l'utilisation des pointeurs en C++ :

variable permet d'accéder à la valeur de la variable.


&variable permet d'accéder à l'adresse de la variable.
Pour un pointeur int *pointeur :
pointeur permet d'accéder à la valeur du pointeur, c'est-à-dire à l'adresse de la variable pointée.
*pointeur permet d'accéder à la valeur de la variable pointée.
Il est important de pratiquer avec des pointeurs pour bien les comprendre, car cette notion peut
être complexe au début. La pratique et la révision sont essentielles pour maîtriser les pointeurs en
programmation.
L'allocation dynamique
Vous vouliez savoir à quoi servent les pointeurs ? Vous êtes sûrs ? Bon, alors je vais vous montrer une
première utilisation.

La gestion automatique de la mémoire


Dans notre tout premier chapitre sur les variables, je vous avais expliqué que, lors de la déclaration d'une
variable, le programme effectue deux étapes automatiquement :

Il demande à l'ordinateur de lui fournir une zone dans la mémoire, ce qu'on appelle l'allocation de la mémoire.
Il remplit cette case avec la valeur fournie, ce qui constitue l'initialisation de la variable.
De même, lorsque l'on arrive à la fin d'une fonction, le programme rend automatiquement la mémoire utilisée à
l'ordinateur, ce qui est appelé la libération de la mémoire. Maintenant, nous allons apprendre à effectuer ces
opérations manuellement en utilisant des pointeurs.

Allouer un espace mémoire


Pour demander manuellement une case dans la mémoire, il faut utiliser l'opérateur new.
new demande une case à l'ordinateur et renvoie un pointeur pointant vers cette case.
Code : C++
int *pointeur(0);
pointeur = new int;
La deuxième ligne demande une case mémoire pouvant stocker un entier et l'adresse de cette case est stockée
dans le pointeur. Le mieux est encore de faire appel à un petit schéma (figure suivante).
Ce schéma est très similaire au précédent. Il y a deux cases mémoires utilisées : la case 14563 qui contient une
variable de type int non initialisée et la case 53771 qui contient un pointeur pointant sur la variable.
La particularité ici est que la variable dans la case 14563 n'a pas d'étiquette. Le seul moyen d'y accéder est donc
de passer par le pointeur.
Si vous changez la valeur du pointeur, vous perdez le seul moyen d'accéder à cette case mémoire. Vous ne pourrez donc plus
l'utiliser ni la supprimer ! Elle sera définitivement perdue, mais elle continuera à occuper de l'espace. Cela s'appelle une fuite de
mémoire, et il faut donc être très attentif pour éviter cela.
Une fois allouée manuellement, la variable s 'utilise comme n'importe quelle autre. On doit juste se rappeler qu'il
faut y accéder par le pointeur, en le déréférençant.
Code : C++
int *pointeur(0);
pointeur = new int;
*pointeur = 2; //On accède à la case mémoire pour en modifier la
Valeur La case sans étiquette est maintenant remplie, et la mémoire est donc dans l'état présenté à la figure
suivante.
Une fois que l'on n'a plus besoin de la case mémoire, il faut la rendre à l'ordinateur. Cela se fait via l'opérateur
"delete".
Libérer la mémoire
Une fois que l'on n'a plus besoin de la case mémoire, il faut la rendre à l'ordinateur. Cela se fait via l'opérateur
delete.
Code : C++
int *pointeur(0);
pointeur = new int;
delete pointeur; //On libère la case mémoire
La case est alors rendue à l'ordinateur qui pourra l'employer à autre chose. Le pointeur, lui, existe toujours et il
pointe toujours sur la case, mais vous n'avez plus le droit de l'utiliser.
Après avoir fait appel à "delete", il est donc essentiel de supprimer cette « flèche » en mettant le pointeur
à l'adresse 0. Ne pas le faire est une cause très courante de plantage des programmes.
Code : C++
int *pointeur(0);
pointeur = new int;
delete pointeur; //On libère la case mémoire
pointeur = 0; //On indique que le pointeur ne pointe plus
vers rien
N'oubliez pas de libérer la mémoire. Si vous ne le faites pas, votre programme risque d'utiliser de plus en plus de
mémoire, jusqu'au moment où il n'y aura plus aucune case disponible ! Votre programme va alors planter.

Un exemple complet
Terminons cette section avec un exemple complet : un programme qui demande l'âge de l'utilisateur et qui
l'affiche à l'aide d'un pointeur.
Code : C++
#include <iostream>
using namespace std;
int main()
{
int* pointeur(0);
pointeur = new int;
cout << "Quel est votre age ? ";
cin >> *pointeur;
//On écrit dans la case mémoire pointée par le pointeur
'pointeur'
cout << "Vous avez " << *pointeur << " ans." << endl;
//On utilise à nouveau *pointeur
delete pointeur; //Ne pas oublier de libérer la mémoire
pointeur = 0; //Et de faire pointer le pointeur vers rien
return 0;
}
Effectivement, l'allocation dynamique de mémoire avec new et la libération avec delete offre un contrôle
précis, mais ajoute de la complexité. Dans de nombreux cas, cela n'est pas nécessaire, mais la
compréhension de ces concepts est essentielle pour gérer efficacement la mémoire dans des projets plus
complexes ou avec des structures de données personnalisées. Cela évite les fuites de mémoire et les
problèmes de gestion des ressources.
Quand utiliser des pointeurs
Bien sûr, je comprends que vous souhaitiez des explications sur les cas d'utilisation des pointeurs. Les trois
cas que vous avez mentionnés sont effectivement des situations courantes où l'utilisation de pointeurs peut
être nécessaire et utile. Pour partager une variable entre différentes parties de votre programme ou pour
sélectionner une valeur parmi plusieurs options, les pointeurs peuvent être des outils puissants. L'exemple
du jeu de stratégie est également un excellent moyen de comprendre comment les pointeurs peuvent être
appliqués dans la pratique. Cependant, comme vous l'avez mentionné, les détails complets et les exemples
spécifiques dépendent souvent du contexte du projet et de la programmation orientée objet.
Dans un jeu de stratégie, chaque personnage peut avoir une cible précise, et un moyen de représenter cela en
C++ serait d'utiliser des pointeurs. Chaque personnage pourrait avoir un pointeur qui pointe vers sa cible, ce
qui lui permettrait de savoir qui viser et attaquer. L'utilisation de pointeurs serait donc une solution pour
modéliser cette relation entre les personnages et leurs cibles dans le jeu. Cependant, comme vous l'avez
mentionné, les détails de mise en œuvre dépendent du contexte du projet et de la manière dont les objets sont
modélisés en C++.
Code : C++
Personnage *cible; //Un pointeur qui pointe sur un autre
personnage
Dans un jeu de stratégie, les pointeurs peuvent être utilisés pour représenter la relation entre les personnages
et leurs cibles. Un pointeur pourrait pointer vers la cible du personnage, et lorsqu'il n'y a pas de combat en
cours, le pointeur pointerait vers l'adresse 0, indiquant l'absence de cible. L'utilisation du pointeur ici est
analogique à une flèche reliant un personnage à son ennemi. Vous prévoyez même d'explorer davantage ces
concepts dans les futurs chapitres du cours.
Choisir parmi plusieurs éléments
Dans le cas d'un QCM (Questionnaire à Choix Multiples), vous pouvez utiliser un pointeur pour suivre la
réponse choisie par l'utilisateur parmi plusieurs options possibles. Une fois que l'utilisateur a fait son choix,
vous pouvez utiliser le pointeur pour indiquer quelle réponse a été sélectionnée. Cela permet de faire évoluer le
programme en fonction des choix de l'utilisateur.
Code : C++
#include <iostream>
#include <string>
using namespace std;
int main()
{
string reponseA, reponseB, reponseC;
reponseA = "La peur des jeux de loterie";
reponseB = "La peur du noir";
reponseC = "La peur des vendredis treize";
cout << "Qu'est-ce que la 'kenophobie' ? " << endl; //On pose la
question
cout << "A) " << reponseA << endl; //Et on affiche les trois
propositions
cout << "B) " << reponseB << endl;
cout << "C) " << reponseC << endl;
char reponse;
cout << "Votre reponse (A,B ou C) : ";
cin >> reponse; //On récupère la réponse de l'utilisateur
string *reponseUtilisateur(0); //Un pointeur qui pointera sur la
réponse choisie
switch(reponse)
{
case 'A':
reponseUtilisateur = &reponseA; //On déplace le pointeur sur
la réponse choisie
break;
case 'B':
reponseUtilisateur = &reponseB;
break;
case 'C':
reponseUtilisateur = &reponseC;
break;
}
//On peut alors utiliser le pointeur pour afficher la réponse
choisie
cout << "Vous avez choisi la reponse : " << *reponseUtilisateur
<< endl;
return 0;
}
Le troisième cas d'utilisation des pointeurs consiste à permettre au programme d'évoluer en fonction des
choix de l'utilisateur. Un exemple concret serait un questionnaire à choix multiples (QCM), où l'utilisateur doit
choisir parmi plusieurs réponses possibles à une question. Une fois que l'utilisateur a fait son choix, un
pointeur peut être utilisé pour indiquer quelle réponse a été sélectionnée. Cela permet de gérer la réponse de
l'utilisateur plus efficacement sans avoir à répéter le test à chaque fois que vous en avez besoin. C'est un cas
d'utilisation moins courant, mais il peut être utile dans certaines situations où vous devez suivre les choix
dynamiques de l'utilisateur.

En résumé
Chaque variable est stockée en mémoire à une adresse différente.
• Il ne peut y avoir qu'une seule variable par adresse.
• On peut récupérer l'adresse d'une variable avec le symbole &, comme ceci : &variable.
• Un pointeur est une variable qui stocke l'adresse d'une autre variable.
• Un pointeur se déclare comme ceci : int *pointeur; (dans le cas d'un pointeur vers une variable de
type int).
• Par défaut, un pointeur affiche l'adresse qu'il contient. En revanche, si on écrit *pointeur, on obtient la
valeur qui se trouve à l'adresse indiquée par le pointeur.
• On peut réserver manuellement une case en mémoire avec new. Dans ce cas, il faut libérer l'espace en
mémoire dès qu'on n'en a plus besoin, avec delete.
• Les pointeurs sont une notion complexe à saisir du premier coup. N'hésitez pas à relire ce chapitre
plusieurs fois. Vous comprendrez mieux leur intérêt plus loin dans ce cours.

Vous aimerez peut-être aussi