0% ont trouvé ce document utile (0 vote)
11 vues143 pages

Programmation C++

Ce document présente les notions de base de la programmation en C++, y compris la définition du langage, son caractère compilé, et l'utilisation des compilateurs et environnements de développement intégrés. Il aborde également la structure d'un programme C++, la déclaration et l'initialisation des variables, ainsi que les types de données, en mettant l'accent sur le type 'int'. Enfin, il fournit des exemples pratiques et des instructions pour utiliser différents outils de programmation sous Windows.

Transféré par

mohamedadam70
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
11 vues143 pages

Programmation C++

Ce document présente les notions de base de la programmation en C++, y compris la définition du langage, son caractère compilé, et l'utilisation des compilateurs et environnements de développement intégrés. Il aborde également la structure d'un programme C++, la déclaration et l'initialisation des variables, ainsi que les types de données, en mettant l'accent sur le type 'int'. Enfin, il fournit des exemples pratiques et des instructions pour utiliser différents outils de programmation sous Windows.

Transféré par

mohamedadam70
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

Programmation C++ (débutant)/Notions de base 1

Programmation C++ (débutant)/Notions de base


Le cours du chapitre 1 : Notions de base

Les langages de programmation


Le C++ est un langage de programmation : il sert donc à écrire des applications informatiques. Il s'agit d'ailleurs
d'un des langages de programmation les plus utilisés aujourd'hui. Chaque programme en C++ doit être écrit en
respectant des règles d'écriture très strictes que nous étudierons petit à petit.

Un langage compilé
Le C++ est un langage compilé : pour écrire un tel programme, il faut commencer par écrire un ou plusieurs fichiers
source. Ensuite, il faut compiler ces fichiers source grâce à un programme appelé compilateur afin d'obtenir un
programme exécutable. Cette phase s'appelle la compilation. Les fichiers source sont des fichiers texte lisibles dont
le nom se termine en général par .c, .cpp ou .h. Les fichiers exécutables portent en général l'extension .exe sous
windows et ne portent pas d'extension sous Linux.

Les compilateurs
Il existe de très nombreux compilateurs : on peut citer par exemple Visual C++ (de microsoft), C++ Builder (de
Borland), ou encore gcc qui est un excellent compilateur libre.

Les environnements de développement intégrés (EDI)


On programme très souvent en utilisant un environnement de développement intégré : il s'agit d'un ensemble complet
d'outils permettant d'éditer et de modifier des fichiers sources, de les compiler, de lancer l'exécutable, de "déboguer"
le programme, etc... Visual C++ (version express disponible gratuitement), C++ Builder, Dev-cpp (disponible
gratuitement et basé sur gcc) et Code::Blocks (lui aussi gratuit mais plus souvent mis à jour que Dev-cpp) sont des
environnements de développement intégrés.

Le C et le C++
Le langage C est un langage de programmation inventé par MM. Kernighan et Ritchie au début des années 70. Au
début des années 90, Bjarne Stroustrup fait évoluer le langage vers le langage C++ en lui rajoutant notamment les
notions orientées objet. Toutefois, bien que le C++ ait évolué à partir du C, et ait gardé un grand nombre de notions
et de syntaxes de son «ancêtre», il s'agit de deux langages différents (le langage C étant étudié dans un livre dédié).

Aspects pédagogiques
Dans ce cours, nous allons d'abord apprendre les notions non orientées objet du C++ (donc nous étudierons
principalement les notions du langage C), puis seulement dans un second temps nous étudierons les notions orientées
objet. Dans un troisième temps, nous aborderons l'étude des interfaces graphiques. Il existe un débat incessant sur
LA bonne manière de faire : quand faut-il aborder la notion d'objet ? Pour des débutants, je conseille plutôt de
procéder selon ce plan.
On remarquera que la notion d'interface graphique ne sera abordée que tout à la fin du cours : nous commencerons
donc à écrire des programmes en mode texte dont l'interface graphique sera rudimentaire. Ceci est très frustrant pour
le débutant mais semble absolument nécessaire.
Programmation C++ (débutant)/Notions de base 2

Un premier exemple
Nous allons maintenant étudier ce premier exemple :
Exemple 1 : un premier exemple

#include <iostream>
using namespace std;

int main()
{
cout << "BONJOUR";
return 0;
}

La directive #include
On place en général au début du programme un certain nombre d'instructions commençant par #include. Cette
instruction permet d’inclure dans un programme la définition de certains objets, types ou fonctions. Le nom du
fichier peut être soit à l'intérieur des chevrons < et >, soit entre guillemets :
• #include <nom_fichier> Inclut le fichier nom_fichier en le cherchant d'abord dans les chemins
configurés, puis dans le même répertoire que le fichier source,
• #include "nom_fichier" Inclut le fichier nom_fichier en le cherchant d'abord dans le même répertoire
que le fichier source, puis dans les chemins configurés.

using namespace std;


Cette ligne est un peu plus difficile à comprendre : en effet, on indique par cette ligne l'utilisation de l'espace de
nommage std. Un espace de nommage est un ensemble de classes dont cout fait partie. Etant donné que nous voulons
utiliser l'objet cout, nous indiquons que l'on utilisera, par défaut, l'espace de nommage std. Pour simplifier, retenons
que, dès que l'on veut utiliser cin ou cout, on doit écrire cette directive.
Il faut également remarquer que les fichiers d'en-tête standard ne sont désormais plus nommés avec une extension .h
(comme iostream.h). Si ces fichiers d'en-tête sont inclus sans être suivi de la commande using namespace std;, cela
ne fonctionnera pas correctement. Dans certaines versions de g++ , si, lors de la compilation, vous spécifiez un
fichier d'en-tête standard avec une extension .h (comme iostream.h), le compilateur utilisera le fichier "backward"
compatible et vous signifiera un avertissement.

Le fichier iostream
Le fichier iostream contient un certain nombre de définitions d’objets intervenant dans les entrées/sorties du
programme, c’est-à-dire dans l’affichage à l’écran ou dans des fichiers. La définition de cout se trouve dans ce fichier;
pour utiliser cout dans notre programme, il faut inclure au début du programme la ligne suivante :
1. include <iostream>
Ce fichier est fourni par l’éditeur du compilateur : il s’agit d’un fichier C++ standard.
Programmation C++ (débutant)/Notions de base 3

La fonction main()
Notre programme contient une fonction appelée main : c’est à cet endroit que va commencer l’exécution du
programme : exécuter un programme en C++, c’est exécuter la fonction main de ce programme. Tout programme en
C++ doit donc comporter une fonction main.
La fonction main apparaît sous la forme suivante :

int main()
{
on place ici une liste d’instructions en C++
}

La liste d’instructions entre accolades est exécutée séquentiellement : on exécute chaque instruction, dans l’ordre, les
unes après les autres.

cout
Il s’agit du flux de sortie du programme (Console Output : sortie console). Ce flux de sortie est envoyé par défaut
vers l’écran. Il va nous servir à afficher des messages à l’écran en utilisant l'opérateur <<. Cet opérateur à la forme
d'une flèche semblant indiquer le sens de transfert des données (écriture vers la console).
Exemple : cout<<"BONJOUR";
Cette instruction affiche BONJOUR à l’écran.
Un autre exemple :
cout<<endl;
Lorsqu'on envoie endl (End of Line : fin de la ligne) vers l'affichage, on passe à la ligne suivante.
Il faut également connaître une écriture plus condensée. Au lieu d’écrire en 3 instructions :

cout << "BONJOUR";


cout << endl;
cout << "AU REVOIR";

On peut écrire en une seule instruction :

cout << "BONJOUR" << endl << "AU REVOIR";

Cependant, sur certaines implémentation, cette instruction condensée ne compile pas correctement, car
l'implémentation du symbole endl ne permet pas d'utiliser l'opérateur << par la suite :

cout << "BONJOUR" << endl;


cout << "AU REVOIR";
Programmation C++ (débutant)/Notions de base 4

Retour de la fonction
La dernière instruction de notre programme est return 0; Elle indique seulement que la fonction main s'est
terminée correctement sans erreur particulière.

Exécution du programme
Lorsqu'on édite notre fichier source, puis compile et enfin exécute notre programme il s'affiche alors à l'écran :

BONJOUR

Remarque
L'ajout de l'instruction system("PAUSE"); sera parfois nécessaire pour que le programme ne s'arrête pas
immédiatement après s'être ouvert. Cette instruction doit être ajouté avant l'instruction return 0;.

Aspect pratique

Utiliser Dev-Cpp sous Windows


• Lorsque vous lancez Dev C++, vous voyez apparaitre l'écran ci-contre.

• Pour créer un nouveau projet, il faut choisir dans le menu Fichier puis Nouveau puis Projet.
Programmation C++ (débutant)/Notions de base 5

• Il faut faire le choix "Empty project".


Il faut taper le nom du projet dans le champs texte Nom. On clique sur le bouton OK.

• Il s'ouvre alors une fenêtre qui nous permet de créer le répertoire de notre projet.
Programmation C++ (débutant)/Notions de base 6

On clique sur enregistrer pour y enregistrer notre fichier de projet dont l'extension est .dev.

• Pour rajouter un nouveau fichier source dans notre projet, il faut choisir dans le menu Fichier, puis Nouveau puis
Fichier Source.
Programmation C++ (débutant)/Notions de base 7

• Une fenêtre nous demande si on veut vraiment ajouter un nouveau fichier au projet : on clique sur Yes.

• On sauvegarde ensuite ce fichier en choisissant dans le menu Fichier, puis Sauvegarder.

• On nous demande alors le nom du fichier à ajouter: ici on l'a appelé [Link].
Programmation C++ (débutant)/Notions de base 8

On clique ensuite sur enregistrer.

• On tape alors notre ficher source.


On l'enregistre en cliquant sur Fichier puis Enregistrer. Pour une application en mode texte, il est recommandé de
rajouter l'instruction system("PAUSE") juste avant l'instruction return 0;.
Programmation C++ (débutant)/Notions de base 9

• Pour compiler notre programme, on choisit dans le menu Exécuter puis Tout reconstruire.

• Les éventuelles erreurs de compilation apparaissent dans la fenêtre du bas.


Programmation C++ (débutant)/Notions de base 10

• Pour exécuter le programme, il suffit de choisir dans le menu Exécuter suivi de Exécuter.

• On voit alors apparaitre à l'écran l'exécution de notre programme.


Programmation C++ (débutant)/Notions de base 11

Utiliser Visual C++ sous Windows


• Lorsque vous lancez Visual c++,vous obtenez cet écran

• Pour créer un nouveau projet il faut cliquer dans fichier->nouveau

• Puis sur Clr Console application,ensuite donnez un nom à votre projet dans le champ name
Programmation C++ (débutant)/Notions de base 12

• Tapez votre code

• Et appuyez sur F5 ,votre application se lance


'À compléter'
Programmation C++ (débutant)/Notions de base 13

Utiliser MinGW/MSys/Cmake sous windows


Si vous projetez de programmer à partir de divers libraires c++ issus de projets tiers, il est fortement déconseillé
d'utiliser dev-cpp ou visual c++. Les outils MinGW, MSys et Cmake sont plus efficaces et souples.

Installer g++
g++ est généralement présent dans les paquets de votre distribution. Cependant, il n'est pas évident qu'il soit installé
par défaut.
Sous Debian: apt-get install g++
Sous d'autres : utilisez votre gestionnaire de paquets (yum, urpmi, rpmdrake, synaptic...)

Éditer le code
L'édition d'un fichier se fait avec un éditeur de texte : on pourra citer emacs, vi et ses variantes, et plein d'autres.
Il faut sauvegarder le fichier par exemple sous le nom "[Link]".

Compilation
Depuis un terminal, on se place dans le répertoire contenant notre fichier à compiler.
cd ./monjolicode
puis la commande la plus simple pour compiler est:
g++ [Link]
qui génèrera un fichier nommé ./[Link] si tout se passe bien (ie si votre code ne génère pas d'erreurs de compilation).
Pour générer un fichier portant un nom bien précis, on peut utiliser les commandes suivantes :
• sous Unix/Linux : g++ [Link] -o main
• sous Windows : g++ [Link] -o [Link]
La première commande génèrera un fichier nommé "main", et la deuxième un fichier "[Link]".
Il est vivement conseillé de regarder le manuel de g++. On pourra notamment être intéressé par les options de
compilation comme l'optimisation (gain généralement important d'efficacité).
à compléter

Exercices du chapitre 1
1) En utilisant l'environnement de développement de votre choix, écrire, compiler et exécuter un programme qui
affiche bonjour à l'écran.
Programmation C++ (débutant)/Notion de variable 1

Programmation C++ (débutant)/Notion de


variable
Le cours du chapitre 2 : la notion de variable
1. Les variables
Une variable est un certain endroit en mémoire permettant de stocker une valeur. En C++, les variables sont
typées : elles contiennent soit un entier, un réel, un caractère, … Le type va exprimer la nature des données
contenues dans notre variable. Les variables portent un nom appelé identificateur.
2. Déclaration des variables
Avant d’utiliser une variable, il faut la déclarer, c'est-à-dire fournir son nom et son type. La déclaration d'une
variable est obligatoire. Le nom de la variable s'appelle l'identificateur. Le type de la variable indique la nature
des données que va contenir cette variable : un entier, un réel, un caractère,…
Syntaxe de la déclaration : type identificateur ;
Exemple : int a;
Cette déclaration déclare une variable a de type int.
3. Intérêt de la déclaration
La déclaration des variables permet au programmeur d'indiquer la nature des données qui vont être stockées dans
ces variables. Loin d'être un handicap, la déclaration permet d'éviter de nombreux bogues. Il s'agit d'un garde-fou
qui évite au programmeur de nombreuses erreurs.
4. Initialisation des variables
En C++, les variables ont une valeur quelconque après leur déclaration. Le programmeur doit donc initialiser les
variables de son programme, sinon elles contiendront n'importe quoi. L'oubli d'initialisation d'une variable est un
bogue très fréquent.
5. Identificateurs valides
Un identificateur est constitué d'une suite des lettres, de chiffres et _ (underscore). Un identificateur ne peut pas
commencer par un chiffre. Il ne peut pas contenir d'espaces, ni contenir le caractères - (tiret) qui serait interprété
comme un moins. Il doit être explicite c'est-à-dire qu'il doit être en rapport avec ce que contient la variable. Si une
variable contient le prix d'un kg de tomates, on va appeler notre identificateur prix_tomate par exemple.
6. Le type int
Il s'agit d'un type de base prédéfini dans le langage C++. Il permet de manipuler des entiers positifs ou négatifs.
En général sur 32 bits : les données sont représentées en complément à 2. On peut alors représenter tous les
entiers de -2^31 à 2^31-1. Le nombre de bits et le système de représentation des données n'est pas déterminée en
C++, ce qui pose de gros problèmes de portabilité des programmes. La manipulation des entiers est exacte sans
erreur de calcul !
7. L'affectation
L'affectation permet d'effectuer des calculs et de transférer le résultat dans une certaine variable.
Syntaxe : identificateur= expression ;
On commence par évaluer l’expression. On met le résultat dans la variable identificateur. L'écriture d'une valeur
dans une variable remplace la valeur précédente qui est "écrasée". Il doit y avoir une correspondance des types.
8. Exemple 1 : utilisation d'une variable entière

#include <iostream>
using namespace std;

int main()
{
Programmation C++ (débutant)/Notion de variable 2

int a;
a = 80 + 20;
cout << "La valeur de a est : " << a << endl;
return 0;
}

•Dans cet exemple, nous déclarons une variable entière a grâce à la déclaration int a;.
•Nous utilisons ensuite l'affectation pour mettre dans a le résultat de l'expression 80+20, c'est-à-dire 100.
•Nous affichons alors la valeur de a grâce à cout.
•Exécution de l'exemple 1
Lorsqu'on exécute notre programme, il s'affiche à l'écran :
La valeur de a est 100
9. Exemple 2 : incrémentation d'une variable

#include <iostream>
using namespace std;

int main()
{
int a;
a = 80;
a = a + 1;
cout << "La valeur de a est : " << a << endl;
return 0;
}

• L'expression a = a + 1; peut paraitre étrange : elle permet d'augmenter de 1 la valeur de a; a vaut 80 avant
l'exécution de cette instruction. a vaut 81 après cette exécution.
• A la place de a=a+1; , on peut également écrire a++;.
• Exécution de l'exemple 2
Lorsqu'on exécute notre programme, il s'affiche à l'écran :
La valeur de a est 81
10. Exemple 3 : utilisation de plusieurs variables

#include <iostream>
using namespace std;

int main()
{
int a, bb = 9, c80;

a = 80;
a++;
bb = bb + a;
c80 = bb - 10;
cout << "La valeur de a est : " << a << endl;
cout << "La valeur de bb est : " << bb << endl;
cout << "La valeur de c80 est : " << c80 << endl;
Programmation C++ (débutant)/Notion de variable 3

return 0;
}

•Dans ce nouvel exemple, nous déclarons dans un premier temps 3 variables a,bb et c80.
•Nous effectuons différentes affectations sur ces variables.
•Nous affichons finalement le contenu final de ces variables.
•Exécution de l'exemple 3
Lorsqu'on exécute notre programme, il s'affiche à l'écran :
La valeur de a est 81
La valeur de bb est 90
La valeur de c80 est 80
11. Différentes opérations
On peut additionner 2 entiers grâce à l'opérateur +.
On peut soustraire 2 entiers grâce à l'opérateur -.
On peut multiplier 2 entiers grâce à l'opérateur *.
On peut diviser 2 entiers grâce à l'opérateur /. Il y a alors arrondi par troncature du résultat.
On peut calculer le reste de la division de a par b grâce à l'opérateur %
12. Exemple 4 : utilisation de différentes opérations

#include <iostream>
using namespace std;

int main()
{
int a = 10, b = 20, c, d, e, f;
c = a + b;
d = a * c;
d = d - 80;
e = d / 7;
f = e % 4;

cout << "La valeur de f est : " << f << endl;

return 0;
}

Lorsqu'on exécute notre programme, il s'affiche à l'écran :


La valeur de f est 3
13. cin
Il s’agit du flux d’entrée du programme. Par défaut le flux d'entrée d'un programme en C++ provient du clavier.
En pratique, le cin permet d’envoyer le contenu de ce qui est saisit au clavier dans une variable.
Exemple : cin>>i;
Lorsque le programme exécute cette instruction, le programme s'arrête et attend que l'utilisateur tape au clavier
une valeur entière. Lorsque l'utilisateur appuiera sur entrée , la valeur tapée ira dans la variable i.
14. Exemple 5 : utilisation de cin

#include <iostream>
using namespace std;
Programmation C++ (débutant)/Notion de variable 4

int main()
{
int a;
cout << "Tapez la valeur de a : ";
cin >> a;
a = a + 10;
cout << "La valeur de a est : " << a << endl;

return 0;
}

• Dans cet exemple, nous déclarons une variable a.


• Nous saisissons ensuite au clavier la valeur de a.
• Nous effectuons un calcul sur cette variable.
• Nous affichons ensuite la valeur finale de a.
• Lorsqu'on exécute notre programme, il s'affiche à l'écran :
Tapez la valeur de a : 80
La valeur de a est 90.
Remarque : dans cet exemple, l'utilisateur a choisi de taper la valeur 80 pour a.
15. Le type double
Le type double est un autre type prédéfini du langage C++. Il permet de stocker un réel. En général sur 64 bits, le
format de représentation est souvent le format IEEE754. La taille et le système de représentation n'est pas imposé
par le langage. Chaque opération peut être entachée d’une minuscule erreur de calcul. La propagation de cette
erreur de calcul peut devenir dramatique !
16. Exemple 6 : utilisation du type double

#include <iostream>
using namespace std;

int main()
{
double a, b, moy;

cout << "Tapez une valeur réelle : ";


cin >> a;
cout << "Tapez une valeur réelle : ";
cin >> b;

moy = (a + b) / 2;

cout << "la moyenne des 2 réels est : " << moy <<endl;

return 0;
}

• Dans ce programme, on demande à l'utilisateur de taper successivement 2 valeurs réelles a et b.


• On calcule dans la variable moy la moyenne de a et de b.
• On affiche ensuite cette moyenne.
Programmation C++ (débutant)/Notion de variable 5

• Exécution de l'exemple 6
Lorsqu'on exécute notre programme, il s'affiche à l'écran :
Tapez une valeur réelle : 6.4
Tapez une valeur réelle : 3.2
La moyenne des 2 réels est : 4.8
17. Compatibilité int-double
Les int et les double ne sont pas du tout représentés de la même manière. On peut sans problème copier un int
dans un double :

int a;
double b;
b=a;

Pour mettre un double dans un int, il faut utiliser ce qu'on appelle un cast : on demande explicitement au
compilateur de transformer le double en int et il y a alors troncature du double :

int a;
double b;
a=(int)b;

18. Exemple 7 : mettre un int dans un double

#include <iostream>
using namespace std;

int main()
{
int a;
double b;
cout << "Tapez une valeur entière : ";
cin >> a;

b = a;

cout << "La valeur de b vaut : " << b <<endl;

return 0;
}

•Dans ce programme, on déclare une variable entière (de type int) a et une variable réelle (de type double) b.
•On demande à l'utilisateur de saisir la valeur de a.
•On met la valeur de a dans la variable b : cette opération s'effectue sans cast.
•On affiche ensuite la valeur de b.
•Exécution de l'exemple 7
Lorsqu'on exécute notre programme, il s'affiche à l'écran :
Tapez une valeur entière : 18
La valeur de b vaut : 18
19. Exemple 8 : mettre un double dans un int

#include <iostream>
using namespace std;
Programmation C++ (débutant)/Notion de variable 6

int main()
{
double a;
int b;

cout << "Tapez une valeur réelle : ";


cin >> a;

b = (int)a;

cout << "La valeur de b vaut : " << b <<endl;

return 0;
}

• Dans ce programme, on déclare une variable réelle (de type double) a et une variable entière (de type int) b.
• On demande à l'utilisateur de saisir la valeur de a.
• On met la valeur de a dans la variable b : cette opération s'effectue avec un cast. Il y aura troncature de la
valeur de a.
• On affiche ensuite la valeur de b.
• Exécution du l'exemple 8
Lorsqu'on exécute notre programme, il s'affiche à l'écran :
Tapez une valeur réelle : 6.78
La valeur de b vaut : 6
20. Les commentaires
Il est recommandé d'inclure dans tout programme des commentaires permettant de rendre le programme plus
facilement compréhensible. Un programme doit être compréhensible par un autre programmeur : dans 6 mois,
vous aurez oublié comment marche votre programme ou un autre programmeur peut être amené à le [Link]
compilateur ne tient pas compte de tout ce qui est en commentaire !
Les commentaires se présentent sous 2 formes:
• Commentaires sur plusieurs lignes commençant par /* et finissant par */.
/*kkkkkkk JJJJJJJJJJJJJJ*/
• Commentaires sur une seule ligne commençant par //
// kkkkkkkkkkkkkkkkkk
21. Exemple 9 : les commentaires

/****************************************
MON PROGRAMME, AUTEUR : MOI
*****************************************/

#include <iostream>
using namespace std;

int main()
{
double a; int b;
Programmation C++ (débutant)/Notion de variable 7

// Saisie de la variable a
cout << "Tapez une valeur réelle : ";
cin >> a;

// On met a dans un entier


b = (int)a;

/* Affichage */
cout << "La valeur de b vaut : " << b <<endl;

return 0;
}

Exercices du chapitre 2

EXERCICE 1
Écrire un programme qui demande à l'utilisateur de taper la largeur et la longueur d'un champ et qui en affiche le
périmètre et la surface.

EXERCICE 2
Écrire un programme qui demande à l'utilisateur de taper 5 entiers et qui affiche leur moyenne. Le programme ne
devra utiliser que 2 variables.

EXERCICE 3
Écrire un programme qui demande à l’utilisateur de saisir 2 entiers A et B, qui échange le contenu des variables A et
B puis qui affiche A et B.

EXERCICE 4
Écrire un programme qui demande à l'utilisateur de taper le prix HT d'un kilo de tomates, le nombre de kilos de
tomates achetés, le taux de TVA (Exemple 5.5, 19.6,...). Le programme affiche alors le prix TTC des marchandises.

EXERCICE 5
Ecrire un programme qui demande à l’utilisateur de saisir les coordonnées de deux points du plan A et B et qui
affiche la distance entre A et B.
Indication 1 : on pourra utiliser le théorème de Pythagore.
Indication 2 : dans le fichier include cmath, il y a une fonction sqrt qui calcule la racine carrée.
Exemple d’utilisation : x = sqrt(y)
x et y doivent être des double.
</pre>
Fonction racine carré : sqrt(nombre)
Fonction carré : pow(nombre, 2)
Les résultats renvoyés par des deux fonctions précédentes sont de type 'double'.
Programmation C++ (débutant)/Instructions if, if...else et switch 1

Programmation C++ (débutant)/Instructions if,


if...else et switch
Le cours du chapitre 3 : le if, le if...else et le switch

Les structures de contrôle


Ce sont des structures permettant d'exécuter certaines instructions de manière conditionnelle ou répétitive. Nous
verrons dans ce chapitres les structures de contrôles de type conditionnelles :
• le if,
• le if else,
• le switch.

Le if
Cette structure de contrôle permet d'exécuter une instruction ou une suite d'instructions seulement si une condition
est vraie.

Syntaxe :
if (condition) instruction;

On évalue la condition :
• si elle est vraie on exécute l’instruction et on passe à l’instruction suivante,
• si elle est fausse on passe directement à l’instruction suivante.
L’instruction peut être remplacée par une suite d ’instructions entre accolades

Les conditions
Les conditions habituelles sont utilisables :
• if (a>b)… strictement supérieur à
• if (a>=b)… supérieur ou égal à
• if (a<b)… strictement inférieur à
• if (a<=b)… inférieur ou égal à
• if (a==b)… test d'égalité
• if (a!=b)… différent de

Une erreur classique


Pour effectuer un test d'égalité, il faut utiliser 2 fois le symbole =.
Par exemple :

if(a==b)…

Une erreur classique consiste à écrire :

if(a=b)…
Programmation C++ (débutant)/Instructions if, if...else et switch 2

Exemple 1 : utilisation du if
Exemple 1 : utilisation du if

#include <iostream>
using namespace std;

int main()
{
int a;
cout << "Tapez la valeur de a : ";
cin >> a;
if (a > 10) cout << "Gagné !" << endl;
cout << "Le programme est fini" << endl;
return 0;
}

• Ce programme demande à l'utilisateur de saisir une valeur entière a.


• Si la valeur tapée est strictement supérieure à 10 on affiche "Gagné" puis "Le programme est fini" et le
programme s'arrête.
• Dans le cas contraire, on affiche uniquement "le programme est fini" et le programme s'arrête.

Exécution n°1 de l'exemple 1


Lorsqu'on exécute notre programme, il s'affiche à l'écran :

Tapez la valeur de a : 80
Gagné
Le programme est fini

Exécution n°2 de l'exemple 1


Lorsqu'on exécute notre programme, il s'affiche à l'écran :

Tapez la valeur de a : 8
Le programme est fini

Exécution n°3 de l'exemple 1


Tapez la valeur de a : 10
Le programme est fini

Le if ... else
Cette structure de contrôle permet d'exécution soit l'instruction1, soit l'instruction 2 en fonction du résultat d'une
condition.
Syntaxe :

if (condition) instruction1;
else instruction2;

1. On évalue la condition,
2. si elle est vraie, on exécute l’instruction1 et on passe à l’instruction suivante,
3. si elle est fausse, on exécute l’instruction2 et on passe à l’instruction suivante.
Programmation C++ (débutant)/Instructions if, if...else et switch 3

L’instruction1 ou l’instruction2 peuvent être remplacées par une suite d’instructions entre accolades.

Exemple 2 :Utilisation du if ...else


Exemple 2 : utilisation du if... else

#include <iostream>
using namespace std;

int main()
{
int a;
cout<<"Tapez la valeur de a : ";
cin>>a;
if(a>10)cout<<"Gagné !"<<endl;
else cout<<"Perdu"<<endl;
cout<<"le programme est fini"<<endl;
return 0;
}

• Ce programme demande à l'utilisateur de saisir une valeur entière a.


• Si la valeur tapée est strictement supérieure à 10, on affiche "Gagné" puis "Le programme est fini" et le
programme s'arrête.
• Dans le cas contraire, on affiche "Perdu" puis "Le programme est fini" et le programme s'arrête.

Exécution n°1 de l'exemple 2


Lorsqu'on exécute notre programme, il s'affiche à l'écran :

Tapez la valeur de a : 80
Gagné
Le programme est fini

Exécution n°2 de l'exemple 2


Lorsqu'on exécute notre programme, il s'affiche à l'écran :

Tapez la valeur de a : 5
Perdu
Le programme est fini

Exécution n°3 de l'exemple 2


Lorsqu'on exécute notre programme, il s'affiche à l'écran :

Tapez la valeur de a : 10
Perdu
Le programme est fini

Les conditions complexes


Il est souvent nécessaire d'écrire des conditions assez compliquées. Il faudra alors utiliser le ET logique, le OU
logique et le NON logique. Il faudra une certaine habitude pour ne pas confondre ces différents opérateurs.
Programmation C++ (débutant)/Instructions if, if...else et switch 4

Le ET logique

Syntaxe
condition1 && condition2

Exemple 3 : utilisation du ET logique


Exemple 3 : utilisation du ET logique

#include <iostream>
using namespace std;
int main()
{
int a;
cout<<"Tapez une valeur entière : ";
cin>>a;
if(a>10 && a<20)cout<<"GAGNÉ"<<endl;
else cout<<"PERDU"<<endl;
return 0;
}

• Dans ce programme, on demande à l'utilisateur de taper une variable entière a.


• Si la valeur tapée est comprise entre 11 et 19 bornes incluses on affiche "GAGNÉ".
• Dans le cas contraire, on affiche "PERDU".
• Exécution de l'exemple 3 n°1
Lorsqu'on exécute notre programme, il s'affiche à l'écran :
Tapez une valeur entière : 8
PERDU
• Exécution de l'exemple 3 n°2
Lorsqu'on exécute notre programme, il s'affiche à l'écran :
Tapez une valeur entière : 15
GAGNÉ
• Exécution de l'exemple 3 n°3
Lorsqu'on exécute notre programme, il s'affiche à l'écran :
Tapez une valeur entière : 20
PERDU

Le OU logique
Syntaxe : condition1 || condition2
Rappel sur le OU logique:
VRAI OU VRAI = VRAI
VRAI OU FAUX = VRAI
FAUX OU VRAI = VRAI
FAUX OU FAUX = FAUX
Programmation C++ (débutant)/Instructions if, if...else et switch 5

Exemple 4 : Utilisation du OU logique


Exemple 4 : utilisation du OU logique

#include <iostream>
using namespace std;

int main()
{
int a;
cout<<"Tapez une valeur entière : ";
cin>>a;
if( a<3 || a>20 )cout<<"GAGNÉ"<<endl;
else cout<<"PERDU"<<endl;
return 0;
}

• Dans ce programme, on demande à l'utilisateur de taper une variable entière a.


• Si la valeur tapée est strictement plus petite que 3 on affiche "GAGNÉ".
• Si la valeur tapée est strictement plus grande que 20 on affiche "GAGNÉ".
• Dans le cas contraire, on affiche "PERDU".
• Exécution de l'exemple 4 n°1
Lorsqu'on exécute notre programme, il s'affiche à l'écran :
Tapez une valeur entière : -6
GAGNÉ
• Exécution de l'exemple 4 n°2
Lorsqu'on exécute notre programme, il s'affiche à l'écran :
Tapez une valeur entière : 3
PERDU
• Exécution de l'exemple 4 n°3
Lorsqu'on exécute notre programme, il s'affiche à l'écran :
Tapez une valeur entière : 21
GAGNÉ

Le NON logique
Syntaxe : !(condition)
Rappel sur le NON logique :
! VRAI=FAUX
!FAUX=VRAI

Exemple 5 : Utilisation du NON logique


Exemple 5 : utilisation du NON logique

#include <iostream>
using namespace std;
int main()
{
int a;
cout<<"Tapez une valeur entière : ";
Programmation C++ (débutant)/Instructions if, if...else et switch 6

cin>>a;
if(!(a<3 || a>20))cout<<"GAGNÉ"<<endl;
else cout<<"PERDU"<<endl;
return 0;
}

• Dans ce programme, on demande à l'utilisateur de taper une valeur entière a.


• Si la condition assez complexe ( !(a<3 || a>20)) est vraie on affiche "GAGNÉ" sinon on affiche "PERDU".
• En fait, on affichera "GAGNÉ" si a est compris entre 3 et 20 bornes incluses.
• Exécution de l'exemple 5 n°1
Lorsqu'on exécute notre programme, il s'affiche à l'écran :
Tapez une valeur entière : 2
PERDU
• Exécution de l'exemple 5 n°2
Lorsqu'on exécute notre programme, il s'affiche à l'écran :
Tapez une valeur entière : 20
GAGNÉ
• Exécution de l'exemple 5 n°3
Lorsqu'on exécute notre programme, il s'affiche à l'écran :
Tapez une valeur entière : 50
PERDU

Exemple 6 : Mettre plusieurs instructions dans un if


Exemple 6 : Mettre plusieurs instructions dans un if

#include <iostream>
using namespace std;

int main()
{
int a;
cout << "Tapez une valeur entière : ";
cin >> a;
if (a==12) {
cout << "GAGNÉ" << endl;
a = a+1;
}
cout << "La valeur finale de a vaut " << a << endl;
return 0;
}

• Dans ce programme, on demande à l'utilisateur de saisir une valeur entière a.


• Si a vaut 12 alors on va effectuer dans un premier temps deux instructions : on affiche "GAGNÉ" et on
incrémente a de 1. On affiche ensuite la valeur de a qui vaudra 13.
• Si a est différent de 12, on affiche directement la valeur de a qui n'aura pas été modifiée.
• Exécution de l'exemple 6 n°1
Lorsqu'on exécute notre programme, il s'affiche à l'écran :
Tapez une valeur entière : 50
Programmation C++ (débutant)/Instructions if, if...else et switch 7

La valeur finale de a vaut 50


• Exécution de l'exemple 6 n°2
Lorsqu'on exécute notre programme, il s'affiche à l'écran :
Tapez une valeur entière : 12
GAGNÉ
La valeur finale de a vaut 13

Exemple 7 : Mettre plusieurs instructions dans un if ...else


Exemple 7 : Mettre plusieurs instructions dans un if...else

#include <iostream>
using namespace std;

int main()
{
int a;
cout<<"Tapez une valeur entière : ";
cin>>a;
if(a!=10){cout<<"GAGNÉ"<<endl;a=a+1;}
else {cout<<"PERDU"<<endl;a=a-1;}
cout<<"La valeur finale de a vaut "<<a<<endl;
return 0;
}

• Dans ce programme, on demande à l'utilisateur de saisir une valeur entière a.


• Si a est différent de 10 alors on va effectuer dans un premier temps 2 instructions : on affiche "GAGNÉ" et on
incrémente a de 1. On affiche ensuite la valeur de a.
• Si a est égal à 10 alors on va effectuer dans un premier temps 2 instructions : on affiche "PERDU" et on
décrémente a de 1. On affiche ensuite la valeur de a.
• Exécution de l'exemple 7 n°1
Lorsqu'on exécute notre programme, il s'affiche à l'écran :
Tapez une valeur entière : 7
GAGNÉ
La valeur finale de a vaut 8
• Exécution de l'exemple 7 n°2
Lorsqu'on exécute notre programme, il s'affiche à l'écran :
Tapez une valeur entière : 10
PERDU
La valeur finale de a vaut 9
Programmation C++ (débutant)/Instructions if, if...else et switch 8

Le type bool
Il s'agit d'un type de base prédéfini du langage C++. Il permet de stocker une valeur booléenne pouvant prendre 2
valeurs : soit true soit false. Le résultat d’une condition peut être stocké dans un bool.

Exemple 8 : utilisation du type bool


Exemple 8 : utilisation du type bool

#include <iostream>
using namespace std;

int main()
{
int a; bool c,d;
cout<<"Tapez une valeur entière : ";
cin>>a;
c=(a<3);
d=(a>20);
if(c||d)cout<<"GAGNÉ"<<endl;
else cout<<"PERDU"<<endl;
return 0;
}

• Dans ce programme, nous définissons une variable entière a et 2 variable booléennes c et d.


• On demande à l'utilisateur de saisir la variable entière a.
• Dans c, on affecte true si a est strictement plus petit que 3. c vaudra false dans le cas contraire.
• Dans d, on affecte true si a est strictement plus grand que 20. d vaudra false dans le cas contraire.
• Si c ou d est vrai, c'est à dire si a est strictement plus petit que 3 ou si a est strictement plus grand que 20 alors on
affiche "GAGNÉ". On affiche perdu dans le cas contraire.
• Exécution de l'exemple 8
Lorsqu'on exécute notre programme, il s'affiche à l'écran :
Tapez une valeur entière : -6
GAGNÉ

Le switch
Syntaxe :

switch(identificateur)
{
case c1:instruction1;break;
case c2:instruction2;break;
case c3:instruction3;break;
...
default: instruction;break;
}

Sémantique du switch :
On teste la variable définie par l'identificateur. On la compare successivement aux constantes c1, c2, c3,…etc… Si la
variable vaut c1 alors on exécute l’instruction1 et on passe à l’instruction suivante. Si elle vaut c2, on exécute
Programmation C++ (débutant)/Instructions if, if...else et switch 9

l'instruction2 et on passe à l’instruction suivante. Idem s'il vaut c3. Si elle ne vaut ni c1, ni c2, ni c3 alors on exécute
l'instruction après default et on passe à l’instruction suivante. Le default est facultatif. On peut remplacer les
instructions instruction1, instruction2, instruction3 par des suites d'instructions sans mettre d'accolades. Les valeurs
c1, c2,c3 .. sont obligatoirement des constantes.

Exemple 9 : utilisation du switch


Exemple 9 : utilisation du switch

#include <iostream>
using namespace std;

int main()
{
int i;
cout<<"Tapez un entier entre 1 et 3 bornes incluses :";
cin>>i;
switch(i)
{
case 1: cout<<"GAGNÉ"<<endl;
i=i+99;
break;
case 2: cout<<"PERDU n° 2"<<endl;
i=0;
break;
case 3: cout<<"PERDU n°3"<<endl;
i=0;
break;
}
cout<<"La valeur finale de i est "<<i<<endl;
return 0;
}

• On commence par saisir un entier i.


• Il y a ensuite une switch qui permet d'effectuer une série d'instructions en fonction de la valeur de i.
• Les 3 valeurs de i pour lesquelles on effectue une série d'instructions sont 1, 2 et 3.
• Si i vaut une autre valeur le switch ne fait rien car il n'y a pas de default.
• Exécution 1 de l’exemple 9
Tapez un entier entre 1 et 3 bornes incluses :1
GAGNÉ La valeur finale de i est 100
• Exécution 2 de l’exemple 9
Tapez un entier entre 1 et 3 bornes incluses :2
PERDU n°2
La valeur finale de i est 0
• Exécution 3 de l’exemple 9
Tapez un entier entre 1 et 3 bornes incluses :3
PERDU n°3 La valeur finale de i est 0
Programmation C++ (débutant)/Instructions if, if...else et switch 10

Exemple 10 : un autre exemple de switch


Exemple 10 : un autre exemple de switch

#include <iostream>
using namespace std;

int main()
{
int i;
cout<<"Tapez un entier entre 1 et 3 bornes incluses :";
cin>>i;
switch(i)
{
case 1:
cout<<"GAGNÉ"<<endl;
i=i+99;
break;

case 2 :
cout<<"PERDU n° 2"<<endl;
i=0;
break;

case 3 :
cout<<"PERDU n°3"<<endl;
i=0;
break;

default :
cout<<"J'ai dit entre 1 et 3 !!!"<<endl;
i=-1000;
break;
}
cout<<"La valeur finale de i est "<<i<<endl;
return 0;
}

• On commence par saisir un entier i.


• Il y a ensuite une switch qui permet d'effectuer une série d'instructions en fonction de la valeur de i.
• Les 3 valeurs de i pour lesquelles on effectue une série d'instructions sont 1, 2 et 3.
• Si i vaut une autre valeur , on exécute l'instruction après default.
• Exécution 1 de l’exemple 10
Tapez un entier entre 1 et 3 bornes incluses :1
GAGNÉ
La valeur finale de i est 100
• Exécution 2 de l’exemple 10
Tapez un entier entre 1 et 3 bornes incluses :2
PERDU n°2
Programmation C++ (débutant)/Instructions if, if...else et switch 11

La valeur finale de i est 0


• Exécution 3 de l’exemple 10
Tapez un entier entre 1 et 3 bornes incluses :3
PERDU n°3
La valeur finale de i est 0
• Exécution 4 de l’exemple 10
Tapez un entier entre 1 et 3 bornes incluses :5
J'ai dit entre 1 et 3 !!!
La valeur finale de i est -1000

Exercices

EXERCICE 1
Ecrire un programme qui résout l' équation AX+B=0. Bien évidemment, on n'oubliera pas tous les cas particuliers
(notamment les cas "tout x est solution" et "pas de solution").

EXERCICE 2
Ecrire un programme qui demande à l'utilisateur de taper 5 entiers et qui affiche le plus grand. Le programme ne
devra utiliser que 2 variables.

EXERCICE 3
Ecrire un programme qui résout l’équation ax2+bx+c=0 en envisageant tous les cas particuliers.

EXERCICE 4
Ecrire un programme qui demande à l’utilisateur de saisir les coordonnées de 4 points A, B, C et D puis qui affiche
les informations suivantes :
- si A et B sont confondus, on affiche ‘A et B sont confondus’
- si C et D sont confondus, on affiche ‘ C et D sont confondus’
- si A et B ne sont pas confondus et si C et D ne sont pas confondus , on affiche soit ‘AB et CD sont parallèles’, soit
'AB et CD sont confondues', soit ‘AB et CD sont sécantes’. Dans ce dernier cas, on affiche les coordonnées de
l'intersection de AB et de CD.

EXERCICE 5
Ecrire un programme qui demande à l’utilisateur de saisir un entier X et qui affiche la valeur absolue de X.

EXERCICE 7
Ecrire un programme qui demande à l’utilisateur de saisir 3 entiers A, B et C et qui indique si C est compris entre A
et B, bornes incluses.

EXERCICE 8
Ecrire un programme qui demande à l’utilisateur de saisir 4 entiers A, B, C et D, puis qui indique quelle est
l'intersection des intervalles [AB] et [CD].
Programmation C++ (débutant)/Instructions if, if...else et switch 12

EXERCICE 9
Ecrire un programme qui demande à l’utilisateur de saisir un entier A puis qui affiche "ERREUR" si A n'est pas un
nombre impair compris entre 83 et 101 bornes incluses. Dans le cas contraire, on affiche "PAS D'ERREUR".
Programmation C++ (débutant)/Instructions for, while et do...while 1

Programmation C++ (débutant)/Instructions for,


while et do...while
Le cours du chapitre 4 : le for, while et do...while

La notion de boucles
Dans ce chapitre, nous allons étudier les structures de contrôle permettant d'effectuer des boucles : le for, le while et
le do…while. On parle de boucles lorsqu'on répète l'exécution d'une série d'instructions à l'intérieur d'un programme.
La notion de boucle est une des notions à la base de toute l'algorithmique.

Le for
Le for est une structure de contrôle qui permet de répéter un certain nombre de fois une partie d'un programme.
Syntaxe :

for( instruction1 ; condition ; instruction2 )


instruction3 ;

Sémantique du for :
1. on exécute l’instruction1
2. on teste la condition :
• si elle est vraie, on exécute l’instruction3, puis l’instrution2 puis on revient au 2.
• si elle est fausse on passe à l’instruction suivante.
L’instruction3 peut être une suite d'instructions entre accolades.

Exemple 1 : utilisation du for


#include <iostream>
using namespace std;

int main()
{
int i;
for(i=0;i<10;i=i+1)
cout<<"BONJOUR"<<endl;
return 0;
}

• Dans ce programme, il y a une boucle de type for :


• L'instruction 1 est : i=0
• L'instruction 2 est : i=i+1
• Le corps du for comporte une seule instruction : cout<<"BONJOUR"<<endl;
• Exécution pas à pas de l’exemple 1
• i vaut 0
• Le test i<10 est vrai ==> on exécute le corps du for avec i=0
• On exécute i=i+1 ==> i vaut 1
• Le test i<10 est vrai ==> on exécute le corps du for avec i=1
Programmation C++ (débutant)/Instructions for, while et do...while 2

• On exécute i=i+1 ==> i vaut 2


• Le test i<10 est vrai ==> on exécute le corps du for avec i=2
• On exécute i=i+1 ==> i vaut 3
• Le test i<10 est vrai ==> on exécute le corps du for avec i=3
• On exécute i=i+1 ==> i vaut 4
• Le test i<10 est vrai ==> on exécute le corps du for avec i=4
• On exécute i=i+1 ==> i vaut 5
• Le test i<10 est vrai ==> on exécute le corps du for avec i=5
• On exécute i=i+1 ==> i vaut 6
• Le test i<10 est vrai ==> on exécute le corps du for avec i=6
• On exécute i=i+1 ==> i vaut 7
• Le test i<10 est vrai ==> on exécute le corps du for avec i=7
• On exécute i=i+1 ==> i vaut 8
• Le test i<10 est vrai ==> on exécute le corps du for avec i=8
• On exécute i=i+1 ==> i vaut 9
• Le test i<10 est vrai ==> on exécute le corps du for avec i=9
• On exécute i=i+1 ==> i vaut 10
• Le test i<10 est faux ==> on sort du for avec i=10
• Résumé de l’exemple 1
• On a exécuté 10 fois le corps du for.
• Le programme affiche donc 10 fois BONJOUR à l’écran.</pre>

Exemple 2 : un deuxième exemple de for


#include <iostream>
using namespace std;

int main()
{
int i;
for (i=0; i<10; i=i+1)
cout<<"La valeur de i est : "<<i<<endl;
cout<<"La valeur finale de i est : "<<i<<endl;
return 0;
}

• Dans ce programme, il y a une boucle de type for :


• L'instruction 1 est : i=0
• La condition est : i<10
• L'instruction 2 est : i=i+1
• Le corps du for comporte une seule instruction : cout<<"La valeur finale de i est : "<<i<<endl; ** On a exécuté
10 fois le corps du for : **La première fois avec i valant 0. **La dernière fois avec i valant 9. ** On quitte le
for avec i valant 10. *'''Exécution de l’exemple 2''' La valeur de i est : 0 La valeur de i est : 1 La valeur de i est :
2 La valeur de i est : 3 La valeur de i est : 4 La valeur de i est : 5 La valeur de i est : 6 La valeur de i est : 7 La
valeur de i est : 8 La valeur de i est : 9 La valeur finale de i est : 10 === Exemple 3 : encore un exemple de for
! === UNIQ-source-3-5df81f2d7198fec5-QINU * '''On a une boucle de type for ''' **on va exécuter le corps de
la boucle la première fois avec i valant 8, la dernière fois avec i valant 18. ** Lorsqu'on quitte le for, i vaut 19.
*'''Exécution de l’exemple 3''' La valeur de i est : 8 La valeur de i est : 9 La valeur de i est : 10 La valeur de i
Programmation C++ (débutant)/Instructions for, while et do...while 3

est : 11 La valeur de i est : 12 La valeur de i est : 13 La valeur de i est : 14 La valeur de i est : 15 La valeur de i
est : 16 La valeur de i est : 17 La valeur de i est : 18 La valeur finale de i est : 19 === Exemple 4 : un for
décroissant === UNIQ-source-4-5df81f2d7198fec5-QINU *'''Explication du for''' ** Cette fois-ci, à chaque
étape on effectue i--, c'est-à-dire on décrémente i de 1. ** On va donc exécuter le corps du for la première fois
avec i valant 10, la dernière fois avec i valant 4. ** Lorsqu'on quitte le for, i vaut 3. *'''Exécution de l’exemple
4''' La valeur de i est : 10 La valeur de i est : 9 La valeur de i est : 8 La valeur de i est : 7 La valeur de i est : 6
La valeur de i est : 5 La valeur de i est : 4 La valeur finale de i est : 3 === Exemple 5 : un for de 2 en 2 ===
UNIQ-source-5-5df81f2d7198fec5-QINU *'''Explication du for''' ** Cette fois-ci, à chaque étape, on ajoute 2 à
i. ** i va donc valoir successivement 10,12, 14, 16 et 18. ** Lorsque i vaut 20, la condition devient fausse et
on quitte la for. *'''Exécution de l’exemple 5''' La valeur de i est : 10 La valeur de i est : 12 La valeur de i est :
14 La valeur de i est : 16 La valeur de i est : 18 La valeur finale de i est : 20 === Exemple 6 : un for qui ne
s'arrête jamais === UNIQ-source-6-5df81f2d7198fec5-QINU *'''Explications du for''' ** La valeur initiale de i
est 10. ** A chaque étape, on exécute i++. ** La valeur de i sera toujours plus grande que 3. ** La condition
i>3 est toujours vraie ==> le for ne s’arrête jamais.
• Le programmeur voulait certainement écrire i=i-1; au lieu de i++.
• Exécution de l’exemple 6

La valeur de i est : 10
La valeur de i est : 11
La valeur de i est : 12
La valeur de i est : 13
La valeur de i est : 14
...

En fait, le type int étant de taille fixe (16 bits ou 32 bits selon le compilateur) et signé, la boucle se termine quand
la valeur de la variable i dépasse la limite des positifs (+32767 ou +2147483647) :
Si le type int utilise 16 bits :

...
La valeur de i est : 32767
La valeur finale de i est : -32768

Si le type int utilise 32 bits :

...
La valeur de i est : 2147483647
La valeur finale de i est : -2147483648

Le while

Syntaxe
while ( condition )
instruction;

Sémantique du while
1. On teste la condition :
• si elle est vraie, on exécute l’instruction puis on recommence au 1).
• si elle est fausse, on passe à l’instruction suivante.
L’instruction peut être une suite d'instructions entre accolades.
Programmation C++ (débutant)/Instructions for, while et do...while 4

Exemple 7 : un exemple de while


#include <iostream>
using namespace std;

int main()
{
int i=0;
while(i<10)
{
cout<<"La valeur de i vaut : "<<i<<endl;
i++;
}
cout<<"La valeur finale de i vaut : "<<i<<endl;
return 0;
}

• Explications
• La variable i est initialisée à 0.
• A chaque étape, à la fin du corps du while, on incrémente i de 1.
• On exécute donc le corps du while la première fois avec i valant 0, la dernière fois avec i valant 9.
• Lorsqu’on sort du while i vaut 10.
• Exécution de l’exemple 7

La valeur de i est : 0
La valeur de i est : 1
La valeur de i est : 2
La valeur de i est : 3
La valeur de i est : 4
La valeur de i est : 5
La valeur de i est : 6
La valeur de i est : 7
La valeur de i est : 8
La valeur de i est : 9
La valeur finale de i est : 10

Exemple 8 : valider une donnée saisie au clavier


#include <iostream>
using namespace std;

int main()
{
int i;
cout <<"Tapez une valeur entre 0 et 20 bornes incluses : ";
cin>>i;
while (i<0 || i>20)
{
cout <<"ERREUR ! ";
Programmation C++ (débutant)/Instructions for, while et do...while 5

cout <<"Tapez une valeur entre 0 et 20 bornes incluses : ";


cin >> i;
}
return 0;
}

• Explications
• On saisit une première fois la valeur de i par un cin.
• Tant que la valeur saisie ne sera pas comprise entre 0 et 20 (bornes incluses), on affiche ERREUR et on
redemande une nouvelle valeur.
• La condition « la valeur de i n'est pas comprise entre 0 et 20 » s’écrit ( i<0 || i>20 ).
• Ne pas confondre le ET et le OU logique !
• Exécution de l’exemple 8

Tapez une valeur entre 0 et 20 bornes incluses : 30


ERREUR ! Tapez une valeur entre 0 et 20 bornes incluses : -2
ERREUR ! Tapez une valeur entre 0 et 20 bornes incluses : 10

Conseil
On utilisera le for lorsqu’on connaît le nombre d’étapes à réaliser. On utilisera un while dans le cas contraire.
Dans tous les cas, il faut toujours vérifier si on exécute notre boucle le bon nombre de fois. Il faudra vérifier dans
tous les cas que notre boucle n'est pas infinie.

Le do...while

Syntaxe
do {
instruction;
}
while ( condition );

Sémantique du do … while
1. on exécute l’instruction.
2. on évalue la condition.
3. si elle est vraie, on recommence au 1.
4. si elle est fausse, on passe à l'instruction suivante.

Exemple 9 : un exemple de do...while


#include <iostream>
using namesapce std;

int main()
{
int i=0;
do {
cout<<"La valeur de i vaut : "<<i<<endl;
i=i+1;
Programmation C++ (débutant)/Instructions for, while et do...while 6

} while(i<10);
cout<<"La valeur finale de i est "<<i<<endl;
return 0;
}

Exécution de l’exemple 9

La valeur de i vaut : 0
La valeur de i vaut : 1
La valeur de i vaut : 2
La valeur de i vaut : 3
La valeur de i vaut : 4
La valeur de i vaut : 5
La valeur de i vaut : 6
La valeur de i vaut : 7
La valeur de i vaut : 8
La valeur de i vaut : 9
La valeur finale de i est : 10

Récapitulatif des structures de contrôle


Le if et le if … else ne permettent pas de répéter un bout de programme.
Le switch est un if …else amélioré et ne permet pas non plus de répéter un bout de programme.
Le for, le while et le do … while permettent de construire des boucles répétitives.
Attention aux boucles infinies !

Utilisation des structures de contrôle


Au delà de ces exemples pédagogiques, la difficulté d'utilisation de ces structures provient de la difficulté à partir
d'un problème donné d'imaginer une solution sous forme d'un algorithme puis de trouver les structures de contrôle
adaptées pour implémenter cet algorithme. Beaucoup de pratique et de travail sont nécessaires pour mettre en œuvre
ce processus mental complexe.

Exercices sur les structures de contrôle

EXERCICE 1
Ecrire un programme qui demande à l'utilisateur de taper un entier et qui affiche GAGNE si l'entier est entre 56 et 78
bornes incluses PERDU sinon.

EXERCICE 2
Ecrire un programme qui affiche tous les entiers de 8 jusqu’à 23 (bornes incluses) en utilisant un for.

EXERCICE 3
Même exercice mais en utilisant un while.

EXERCICE 4
Ecrire un programme qui demande à l’utilisateur de taper 10 entiers et qui affiche leur somme.
Programmation C++ (débutant)/Instructions for, while et do...while 7

EXERCICE 5
Ecrire un programme qui demande à l’utilisateur de taper 10 entiers et qui affiche le plus petit de ces entiers.

EXERCICE 6
Ecrire un programme qui demande à l'utilisateur de taper un entier N et qui calcule la somme des cubes de 5^3 à
N^3.

EXERCICE 7
Ecrire un programme qui demande à l'utilisateur de taper un entier N et qui calcule u(N) défini par :
u(0)=3
u(n+1)=3.u(n)+4

EXERCICE 8
Ecrire un programme qui demande à l'utilisateur de taper un entier N et qui calcule u(N) défini par :
u(0)=1
u(1)=1
u(n+1)=u(n)+u(n-1)

EXERCICE 9
Ecrire un programme qui demande à l’utilisateur de taper un entier N entre 0 et 20 bornes incluses et qui affiche
N+17. Si on tape une valeur erronée, il faut afficher "erreur" et demander de saisir à nouveau l'entier.

EXERCICE 10
Ecrire un programme qui permet de faire des opérations sur un entier (valeur initiale à 0). Le programme affiche la
valeur de l'entier puis affiche le menu suivant :
1. Ajouter 1
2. Multiplier par 2
3. Soustraire 4
4. Quitter
Le programme demande alors de taper un entier entre 1 et 4. Si l'utilisateur tape une valeur entre 1 et 3, on effectue
l'opération, on affiche la nouvelle valeur de l'entier puis on réaffiche le menu et ainsi de suite jusqu'à ce qu'on tape 4.
Lorsqu'on tape 4, le programme se termine.

EXERCICE 11
Ecrire un programme qui demande à l'utilisateur de taper des entiers strictement positifs et qui affiche leur moyenne.
Lorsqu'on tape une valeur négative, le programme affiche ERREUR et demande de retaper une valeur. Lorsqu'on
tape 0, cela signifie que le dernier entier a été tapé. On affiche alors la moyenne. Si le nombre d'entiers tapés est égal
à 0, on affiche PAS DE MOYENNE.

EXERCICE 12
Ecrire un programme qui demande à l'utilisateur de taper un entier N et qui calcule u(N) défini par :
u(0)=3
u(1)=2
u(n)=n.u(n-1)+(n+1).u(n-2)+n
Programmation C++ (débutant)/Instructions for, while et do...while 8

EXERCICE 13
Ecrire un programme qui demande de saisir 10 entiers et qui affiche le nombre d'occurrences de la note la plus haute.

EXERCICE 14
Ecrire un programme qui demande de saisir un entier N et qui affiche N!.

EXERCICE 15
Ecrire un programme qui demande de saisir un entier et qui indique si cet entier est premier ou non.

EXERCICE 16
Ecrire un programme qui demande à l'utilisateur de saisir un entier N et qui affiche le nombre de nombres premiers
inférieurs ou égaux à N.

EXERCICE 17
Ecrire un programme qui demande à l'utilisateur de saisir un entier N et qui affiche le N-ième nombre premier.

EXERCICE 18
Ecrire un programme qui demande à l'utilisateur de saisir un entier N et qui affiche la figure suivante.

N=1
*
N=2
**
*
N=3
***
**
*

et ainsi de suite

EXERCICE 19
Ecrire un programme qui demande à l'utilisateur de saisir un entier N et qui affiche la figure suivante.

N=1
*
N=2
**
*
N=3
***
**
*

et ainsi de suite.
Programmation C++ (débutant)/Instructions for, while et do...while 9

EXERCICE 20
On considère la suite hongroise : u(0)=a (a entier)
si u(n) pair alors u(n+1)=u(n)/2 sinon u(n+1)=3*u(n)+1
Pour toutes les valeurs a, il existe un entier N tel que u(N)=1 (conjecture admise).
a) Ecrire un programme qui demande à l'utilisateur de taper a et qui affiche toutes les valeurs de u(n) de n=1 à n=N.
b) Ecrire un programme qui demande à l'utilisateur de taper un entier M puis qui cherche la valeur de a comprise
entre 2 et M qui maximise la valeur de N. On appelle A cette valeur. Le programme doit afficher la valeur A et la
valeur N correspondante.
Programmation C++ (débutant)/Les types de base 1

Programmation C++ (débutant)/Les types de


base
Le cours du chapitre 5 : les types de base

Les types int et double


Nous avons déjà étudié précédemment les type int et double pour stocker respectivement un entier et un réel.

Le type char
Le type char est un type prédéfini du langage C++. Il permet de stocker un caractère.
Il est codé en général sur 8 bits.
On peut faire des tests sur le caractère : if(c>='A' && c<='Z') permet par exemple de tester si un caractère est une
lettre majuscule.
On peut transférer un char dans un int. On récupère alors le code ASCII du caractère.

Exemple 1 : utilisation du type char


#include <iostream>
using namespace std;

int main() {
char a, b;
a = 'Y';
cout << "Tapez un caractere : "; cin >> b;
cout << "Le caractère a vaut : " << a <<endl;
cout << "Le caractère b vaut : " << b <<endl;
return 0;
}

• Dans cet exemple,on commence par déclarer 2 variables de type char a et b.


• On peut affecter à la variable a le caractère 'Y' en utilisant l'affectation a='Y';. On notera que Y s'écrit entre cotes
(et non entre des guillemets qui sont réservées aux chaînes de caractères).
• On saisit la valeur de b par un cin.
• On affiche les valeurs de a et b en utilisant cout.
• Exécution 1 de l’exemple 1
Tapez un caractere : Z
Le caractère a vaut Y
Le caractère b vaut Z
Programmation C++ (débutant)/Les types de base 2

Codage des caractères


Chaque caractère est codé en général sur 8 bits sous la forme d'un code ASCII. Le code ASCII est un système de
représentation des caractères où chaque caractère est codé par un entier entre 0 et 127. On peut récupérer ce code en
mettant un caractère dans un entier.

Exemple 2 : le codage des caractères


#include <iostream>
using namespace std;

int main()
{
char c; int i;

do{
cout<<"Saisir une lettre : "; cin>>c;
i=c;
cout <<"Le caractère ASCII de "<<c<<" est : "<<i<<endl;
}while (c!='Q');

cout << "Pressez une touche pour continuer ..." << endl;
[Link]();
[Link]();

return 0;
}

• Explications
• On demande à l'utilisateur de saisir un caractère dans une variable a.
• On récupère le code ASCII de a en mettant a dans une variable entière x.
• On affiche ce code ASCII par un cout.
• Exécution 1
Saisir une lettre : H
Le caractère ASCII de H est : 72
• Exécution 2
Saisir une lettre :w
Le caractère ASCII de w est : 119
Programmation C++ (débutant)/Les types de base 3

Comparaison sur les char


Lorsqu'on effectue des comparaisons sur les char, on compare en fait les codes ascii.
On peut tester si un caractère c est une majuscule par le test (x>='A' && x<='Z').
On peut tester si un caractère c est une minuscule par le test (x>='a' && x<='z').
On peut tester si un caractère c est un chiffre par le test (x>='0' && x<='9').

Exemple 3 : Comparaison sur les char


#include <iostream>
using namespace std;

int main()
{
char a;
cout<<"Tapez un caractere : "; cin>>a;

if (a>='A' && a<='Z') cout<<"Vous avez tapé une majuscule."<<endl;


else if (a>='a' && a<='z') cout<<"Vous avez tapé une minuscule."<<endl;
else if (a>='0' && a<='9') cout<<"Vous avez tapé un chiffre."<<endl;
else cout<<"Vous n'avez tapé ni une majuscule, ni une minuscule, ni un chiffre."<<endl;

return 0;
}

• Explications
• On demande à l'utilisateur de saisir un caractère dans une variable a.
• On teste ensuite si l'utilisateur a tapé une majuscule, une minuscule, un chiffre ou une autre type de caractère.
• On affiche ce code ASCII par un cout.
• Exécution 1
Tapez un caractère : H
Vous avez tapé une majuscule
• Exécution 2
Tapez un caractère : w
Vous avez tapé une minuscule
• Exécution 3
Tapez un caractère : 8
Vous avez tapé un chiffre
• Exécution 4
Tapez un caractère : [
Vous n'avez tapé ni une majuscule, ni une minuscule, ni un chiffre
Programmation C++ (débutant)/Les types de base 4

Transformation char-int
On peut effectuer des opérations de base sur les char : addition et soustraction.
Ces opérations sont en fait réalisée sur les codes ascii.
Si c est un chiffre c-'0' est la valeur de l'entier correspondant à ce chiffre.

Exemple 4 : transformation char-int


#include <iostream>
using namespace std;

int main()
{
char a;
int x;
cout <<"Tapez un caractere : "; cin>>a;

if (a>='0' && a<='9')


{
cout <<"Vous avez tapé un chiffre." <<endl;
x = a-'0';
cout <<"Ce chiffre est : "<< x <<endl;
}
else cout <<"Vous n'avez pas tapé un chiffre." <<endl;
return 0;
}

• Explications
• Dans cet exemple, on demande à l'utilisateur de taper un caractère.
• Si ce caractère est un chiffre, on récupère dans l'entier x la valeur de ce chiffre pas son code ASCII).
• On affiche ensuite la valeur de x.
• Exécution 1
Tapez un caractère : 7
Vous avez tapé un chiffre.
Ce chiffre est 7.
• Exécution 2
Tapez un caractère : 4
Vous avez tapé un chiffre.
Ce chiffre est 4.
• Exécution 3
Tapez un caractère : Y
Vous n'avez pas tapé un chiffre.
Programmation C++ (débutant)/Les types de base 5

Transformation majuscule-minuscule
Pour transformer un caractère c qui est une majuscule en la minuscule correspondante, il suffit de lui ajouter ('a'-'A').
Pour transformer un caractère c qui est une minuscule en la majuscule correspondante, il suffit de lui ajouter ('A'-'a').

Exemple 5 : transformation majuscule-minuscule


#include<iostream>
using namespace std;

int main()
{
char a, b;
cout<<"Tapez un caractere : "; cin>>a;
if (a>='A' && a<='Z') {
cout<<"Vous avez tapé une majuscule."<<endl;
b = a + ('a'-'A');
cout<<"La minuscule correspondante est "<< b <<endl;
}
else if (a>='a' && a<='z') {
cout<<"Vous avez tapé une minuscule."<<endl;
b = a + ('A'-'a');
cout<<"La majuscule correspondante est "<< b <<endl;
}
else cout<<"Vous n'avez pas tapé une lettre."<<endl;
return 0;
}

• Explications
• On demande à l'utilisateur de taper un caractère dans un variable a.
• Si l'utilisateur a tapé une majuscule, on affiche la minuscule correspondante.
• Si l'utilisateur a tapé une minuscule, on affiche la majuscule correspondante.
• Exécution 1
Tapez un caractère : H
Vous avez tapé une majuscule.
La minuscule correspondante est h.
• Exécution 2
Tapez un caractère : w
Vous avez tapé une minuscule.
La majuscule correspondante est W.
• Exécution 3
Tapez un caractère : 9
Vous n'avez pas tapé une lettre.
Programmation C++ (débutant)/Les tableaux statiques 1

Programmation C++ (débutant)/Les tableaux


statiques
Le cours du chapitre 6 : les tableaux statiques

Les tableaux
Une variable entière de type int ne peut contenir qu'une seule valeur. Si on veut stocker en mémoire un ensemble de
valeurs, il faut utiliser une structure de données appelée tableau.
Dans ce chapitre, les tableaux seront statiques : leur taille sera fixée une fois pour toute. Il s'agit d'une structure de
donnée absolument fondamentale pour stocker une liste d'éléments.

Déclaration d'un tableau statique


Syntaxe : type identificateur[taille];
Un tableau sera constitué d'un ensemble de cases. Chaque case comportera un élément dont le type sera type. Le nom
du tableau sera identificateur. Le nombre total de cases du tableau sera taille. Cette variable sera obligatoirement une
constante.

Un exemple de tableau
Déclaration d'un tableau : int a[10];
a est un tableau de 10 cases. Chaque case contient un entier (type int). La première case s’appelle a[0]. La deuxième
case s’appelle a[1] et la dixième case a[9].
Remarque : la case a[10] n’existe pas ! Car la première case possède l'indice 0. Si vous essayez d'accéder à une case
dont l'indice n'est pas valide, le programme "plantera".
Sur chaque case, on peut effectuer les opérations habituelles : addition, affectation…etc…

Exemple 1 : utilisation d'un tableau


#include <iostream>
using namespace std;

int main()
{
int t[10], i;
for(i=0; i<10; i++)
{
cout << "Tapez la valeur numero " << i << " : ";
cin >> t[i];
}
for(i=0; i<10; i++) t[i] = t[i]+1;
for(i=0; i<10; i++) cout << "La valeur numero " << i <<" est : "<< t[i] <<endl;
return 0;
}

• Explications
• Dans ce programme, nous allons tout d'abord saisir une à une le contenu des 10 cases d'un tableau t.
Programmation C++ (débutant)/Les tableaux statiques 2

• Ensuite nous allons effectuer un traitement simple sur ce tableau : nous allons incrémenter de 1 le contenu de
chaque case.
• Finalement, nous afficherons le contenu final de chaque case du tableau.
• Dans ce programme, nous commençons par définir un tableau t de 10 cases de type entier. La première case de
ce tableau sera t[0],… et la dernière t[9].
• La première boucle for permet de saisir une à une les cases du tableau : for(i=0;i<10;i++) { cout<<"Tapez la
valeur numero "<<i<<" : "; cin>>t[i]; } remarque : la première valeur de i pour laquelle le corps du for sera
effectué sera i=0, la dernière i=9
• for(i=0;i<10;i++)t[i]=t[i]+1;
Dans cette boucle for, on augmente de 1 le contenu de chaque case du tableau.
• for(i=0;i<10;i++) cout<<"La valeur numero "<<i<<" est : " <<t[i]<<endl;
On affiche une à une le contenu des cases du tableau.
• Exécution
Tapez la valeur numero 0 : 5
Tapez la valeur numero 1 : 2
Tapez la valeur numero 2 : 50
Tapez la valeur numero 3 : 10
Tapez la valeur numero 4 : 20
Tapez la valeur numero 5 : 60
Tapez la valeur numero 6 : 80
Tapez la valeur numero 7 : 90
Tapez la valeur numero 8 : 10
Tapez la valeur numero 9 : 10
La valeur numero 0 est 6
La valeur numero 1 est 3
La valeur numero 2 est 51
La valeur numero 3 est 11
La valeur numero 4 est 21
La valeur numero 5 est 61
La valeur numero 6 est 81
La valeur numero 7 est 91
La valeur numero 8 est 11
La valeur numero 9 est 11

La taille d'un tableau est une CONSTANTE


La taille d’un tel tableau est obligatoirement constante et connue à la compilation du programme. On parle de tableau
statique.
Interdiction de taper : int i; cin>>i; int t[i];
Lorsque nous aurons étudié les pointeurs et le mot clé new (dans quelques chapitres), nous pourrons créer des
tableaux dont la taille est variable. Patience !
Programmation C++ (débutant)/Les tableaux statiques 3

Déclaration et initialisation d'un tableau


On peut déclarer et initialiser un tableau de la manière suivante : int t[]={8,7,6,4,8};
Le tableau sera toujours un tableau de taille fixe, ici un tableau à 5 cases. Le tableau t n'est pas un tableau de taille
variable.
Cette syntaxe évite d'écrire : int t[5]; t[0]=8; t[1]=7; t[2]=6; t[3]=4; t[4]=8;

Exemple 2 : un tableau de double


#include <iostream>
using namespace std;

int main()
{
double t[4];
int i;
for(i=0; i<4; i++)
t[i] = 1.0 / (i+1);
for(i=0; i<4; i++) cout<<"La valeur numéro "<<i<<" est : " << t[i] <<endl;
return 0;
}

• Explications
• On peut définir un tableau de n’importe quel type : ici un tableau de double. Dans ce programme, nous
définissons un tableau t de 4 double.
• Nous remplissons ensuite ce tableau en mettant 1/(i+1) dans la case numéro i.
• Nous affichons ensuite une à une le contenu de chaque case.
• Exécution
La valeur numero 0 est 1
La valeur numero 1 est 0.5
La valeur numero 2 est 0.33333
La valeur numero 3 est 0.25

Indice d'un élément dans un tableau


Le contenu d'un tableau peut être un int, un double … Ce type est défini lors de la déclaration du tableau et ne peut
pas changer. L'indice d'un élément d'un tableau est lui obligatoirement de type entier.
Par exemple, il est interdit d'écrire :

double a;
double b[10];
a=8;
b[a]=123;
Programmation C++ (débutant)/Les tableaux statiques 4

Traitements sur les tableaux


Nous allons maintenant étudier différents algorithmes standards qu'il faut savoir effectuer sur des tableaux : calcul de
la moyenne, recherche du plus petit élément,…
Ces traitements et recherche en tout genre sont des algorithmes indispensables que doit connaître tout programmeur.

Calcul de la moyenne
• On suppose que des éléments sont stockés dans un tableau contenant 4 cases : on veut calculer la moyenne des
éléments de ce tableau.
• Algorithme utilisé :
On initialise une variable s à 0. Il faudra parcourir le tableau et ajouter à chaque étape l'élément courrant du tableau à
s. On divisera ensuite s par le nombre d'éléments du tableau. Il faut maintenant formaliser cet algorithme.

Exemple 3 : calcul de la moyenne


#include <iostream>
using namespace std;

int main()
{
int t[4], i;
double s=0;
for(i=0; i<4; i++)
{
cout << "Tapez la valeur numéro " << i << " : ";
cin >> t[i];
s = s + t[i];
}

s = s/4;
cout << "La moyenne est : " << s << endl;
return 0;
}

• Explications
• Dans cet exemple, on déclare un tableau t de 4 cases (la première sera t[0], la dernière t[3]).
• Grâce à une boucle for, on saisit une à une le contenu des 4 cases du tableau.
for(i=0;i<4;i++) { cout<<"Tapez la valeur numéro "<<i<<" : "; cin>>t[i]; }
• Pour calculer la somme des éléments d’un tableau, on initialise s à 0 et à chaque étape on ajoute t[i] à s grâce à
la boucle for suivante :
for(i=0;i<4;i++)s=s+t[i];
A la fin de cette boucle, la variable s contient la somme des éléments du tableau.
Remarque 1 : un bug courant dans le calcul d'une somme est d'oublier d'initialiser s à 0 avant la boucle.
Remarque 2 : un autre bug courant est de se tromper dans les bornes de la boucle for.
• Exécution
Tapez la valeur numero 0 : 5
Tapez la valeur numero 1 : 2
Tapez la valeur numero 2 : 50
Programmation C++ (débutant)/Les tableaux statiques 5

Tapez la valeur numero 3 : 10


La moyenne est 16.75

Recherche dans un tableau


On veut écrire un programme qui recherche le plus petit élément dans un tableau contenant 4 cases.
Algorithme utilisé : on va stocker notre plus petit élément dans une variable ppt. On commence par initialiser ppt au
premier élément du tableau (d'indice zéro). On parcourt alors tous les autres éléments du tableau en comparant
l'élément courant à ppt et en mettant éventuellement à jour la valeur de ppt. Il faut maintenant formaliser cet
algorithme.

Exemple 4
#include <iostream>
using namespace std;

int main()
{
int t[4], i, ppt;
for(i=0; i<4; i++)
{
cout << "Tapez la valeur numéro " << i << " : ";
cin >> t[i];
}
ppt = t[0];
for(i=1; i<4; i++) if(ppt>t[i]) ppt=t[i];
cout << "La plus petite valeur est "<< ppt <<endl;
return 0;
}

• Explications
• Pour calculer le plus petit élement d’un tableau, on initialise ppt à t[0].
• On parcourt ensuite le tableau de la case 1 à la dernière case d'indice 3 en comparant t[i] à ppt. Si t[i] est plus
petit que le plus petit courant ppt alors on copie t[i] dans ppt (t[i] devient alors le nouveau plus petit courant).
Dans le cas contraire, on ne modifie pas la valeur de ppt.
• On affiche finalement la valeur de ppt en dehors de la boucle.
• Exécution
Tapez la valeur numero 0 : 9
Tapez la valeur numero 1 : 7
Tapez la valeur numero 2 : 11
Tapez la valeur numero 3 : 15
La plus petite valeur est 7
Programmation C++ (débutant)/Les tableaux statiques 6

Exemple 5 : inverser l'ordre des éléments d'un tableau


#include <iostream>
using namespace std;

int main()
{
int t[6], i, a;

for(i=0; i<6; i++)


{
cout << "Tapez la valeur numéro " << i << " : ";
cin >> t[i];
}

for(i=0; i<3; i++)


{
a = t[i];
t[i] = t[5-i];
t[5-i] = a;
}

for(i=0; i<6; i++)


cout << "La valeur numéro " << i << " est " << t[i] << endl;

return 0;
}

• Explications
• Pour inverser le contenu du tableau t à 6 cases il y a 3 étapes :
Étape 0 : on échange t[0] et t[5]
Étape 1 : on échange t[1] et t[4]
Étape 2 : on échange t[2] et t[3]
• A l’étape i, on échange t[i] et t[5-i].
• Chaque étape sera numérotée de i=0 à i=2.
• Attention de ne pas échanger 2 fois le contenu de chaque case en écrivant par erreur :
for(i=0; i<6; i++){ a=t[i]; t[i]=t[5-i]; t[5-i]=a;}
• Exécution
Tapez la valeur numero 0 : 9
Tapez la valeur numero 1 : 7
Tapez la valeur numero 2 : 11
Tapez la valeur numero 3 : 15
Tapez la valeur numero 4 : 16
Tapez la valeur numero 5 : 4
La valeur numero 0 est 4
La valeur numero 1 est 16
La valeur numero 2 est 15
Programmation C++ (débutant)/Les tableaux statiques 7

La valeur numero 3 est 11


La valeur numero 4 est 7
La valeur numero 5 est 9

Suppression et tassement
On veut supprimer toutes les valeurs valant 9 dans un tableau de 6 cases en décalant tous les élément vers la gauche
et en remplaçant ces éléments par des 0 placés à la fin du tableau.
Exemple :
Valeur initiale du tableau : 9, 8, 9, 9, 9, 6
Valeur finale du tableau : 8, 6, 0, 0, 0, 0
Ce problème paraît simple mais on trouve tellement de solutions fausses à ce problème que, désespérés, nous avons
fini par le mettre dans le cours ! Par exemple, il est complètement inutile d'écrire 2 boucles imbriquées.

Exemple 6 : suppression et tassement


#include <iostream>
#include <iomanip>
using namespace std;

int main()
{
int t[6], i, j = 0;

for (i=0 ; i<6 ; i++)


{
cout << "Tapez la valeur numéro " << i << " : ";
cin >> t[i];
}

for(i=0 ; i<6 ; i++) if (t[i] != 9) { t[j] = t[i]; j++; }


for(i=j ; i<6 ; i++) t[i] = 0;

for(i=0 ; i<6 ; i++) cout << "La valeur numéro " << i << " est " << t[i] << endl;
return 0;
}

Explications
1. Dans cet exemple, on commence par saisir chacun des 6 éléments du tableau.

for(i=0;i<6;i++) { cout<<"Tapez la valeur numéro "<<i<<" : "; cin>>t[i]; }

2. On va utiliser un indice j qui sera l'indice dans le tableau où doit être mis le prochain élément différent de 9. Cet
élément est initialisé à 0.
3. On parcourt une seule fois le tableau et on place les valeurs différentes de 9 dans la case numéro j du tableau en
incrémentant à chaque fois j de 1.

for(i=0 ; i<6 ; i++) if (t[i] != 9) { t[j] = t[i]; j++; }

4. On rajoute ensuite des 0 à partir de la case numéro j jusqu'à la fin du tableau.


Programmation C++ (débutant)/Les tableaux statiques 8

for(i=j ; i<6 ; i++) t[i] = 0;

Les constantes
Imaginons que dans un programme, on utilise un tableau de 100 cases et que l'on effectue des traitements en tout
genre sur ce tableau. Il y aura des tonnes d'endroits dans le programme (au niveau des boucles notamment) où il y
aura des valeurs valant 100 (ou 99). Si on décide de changer la taille de tableau et de la faire passer à 200 : il faudra
faire des tonnes de modifications dans notre programme notamment au niveau des indices des boucles, avec à
chaque fois un risque d'erreur non négligeable.

Une solution : les constantes


On va définir une constante N qui vaudra 100 et on va écrire tout notre programme, notamment tous nos indices de
boucles en fonction de N.
Si on veut changer la taille de tableau, il suffira de changer la valeur de N à un seul endroit dans le programme.

Deux syntaxes pour les constantes


Il y a 2 syntaxes pour définir des constantes : l'une, la plus ancienne est d'utiliser la directive de compilation #define,
l'autre est de définir une variable globale constante. On préférera utiliser cette deuxième solution mais les deux sont à
connaître.
Première syntaxe (version C)
#define nom valeur
Deuxième syntaxe (version C++)
const type identificaleur=valeur_constante;

Exemple 7 : les constantes


#include <iostream>
using namespace std;
#define N 10

int main()
{
int t[N], i;
for (i=0; i<N; i++) t[i] = i*i;
for (i=0; i<N; i++) cout<< t[i] <<endl;
return 0;
}

• Explications
• On définit une macro N valant toujours 10.
• Avant la compilation, toutes les occurrences de N seront remplacées par sa valeur c'est-à-dire 10.
• Tous nos indices de boucles seront calculés en fonction de N.
• Dans ce programme, on déclare un tableau d'entiers à N cases (N est une constante valant 10).
• On met ensuite dans la case i du tableau la valeur i*i et on affiche finalement toutes les cases du tableau.
• Exécution
0
1
4
Programmation C++ (débutant)/Les tableaux statiques 9

9
16
25
36
49
64
81

Exemple 8 : les constantes


#include <iostream>
using namespace std;
const int N=10;

int main()
{
int t[N], i;
for(i=0; i<N; i++) t[i] = i*i;
for(i=0; i<N; i++) cout<< t[i] <<endl;
return 0;
}

• Explications
• Cet exemple est absolument identique au précédent à la différence que N est cette fois-ci une variable globale
constante de type entier valant 10. On préférera utiliser cette solution que d'utiliser #define.
• Dans un programme en C++, il est déconseillé d'utiliser des variables globales qui ne sont pas constantes : cela
nuit en général gravement à la structuration de l'application.

Tableau à 2 dimensions
Si on veut déclarer un tableau de 5 lignes et 4 colonnes, il faut déclarer :
int a[5][4];
On accède alors à l'élément ligne i colonne j de la manière suivante : a[i][j]=99;
Dans cet exemple, i doit être compris entre 0 et 4 (bornes incluses) et j entre 0 et 3 (bornes incluses).

Exemple 9 : un tableau à 2 dimensions


#include <iostream>
using namespace std;
const int N = 2;
const int M = 3;

int main()
{
int i, j;
int t[N][M];

for(i=0; i<N; i++)


for(j=0; j<M; j++)
{
Programmation C++ (débutant)/Les tableaux statiques 10

cout<<"Tapez t["<< i <<"]["<< j <<"] :";


cin >> t[i][j];
}

cout<<"Voici le tableau :"<<endl;


for(i=0; i<N; i++)
{
for(j=0; j<M; j++) cout<< t[i][j] <<" ";
cout<<endl;
}
return 0;
}

• Explications
• Dans cet exemple, on déclare un tableau t d'entiers comportant 2 lignes et 3 colonnes.
• Par 2 boucles imbriquées, on saisit un à un les 6 éléments du tableau.
• On affiche ensuite le contenu du tableau.
• Exécution
Tapez t[0][0] : 3
Tapez t[0][1] : 4
Tapez t[0][2] : 5
Tapez t[1][0] : 6
Tapez t[1][1] : 8
Tapez t[1][2] : 4
Voici le tableau :
345
684

Et maintenant …
Nous avons étudié les types de base, les structures de contrôle et les tableaux, il faut maintenant effectuer des
exercices pour s'entraîner à manipuler des tableaux. Ces manipulations pourront être l'occasion de mettre en oeuvre
des algorithmes classiques de recherche, de suppression de tri …etc…Nous en avons étudié quelques-uns en cours et
il en reste des tonnes à étudier. A vous de jouer !

Exercices

EXERCICE 1
Ecrire un programme qui demande à l'utilisateur de saisir 10 entiers stockés dans un tableau. Le programme doit
afficher le nombre d'entiers supérieurs ou égaux à 10.
Programmation C++ (débutant)/Les tableaux statiques 11

EXERCICE 2
Ecrire un programme qui demande à l'utilisateur de saisir 10 entiers stockés dans un tableau ainsi qu'un entier V. Le
programme doit rechercher si V se trouve dans le tableau et afficher "V se trouve dans le tableau" ou "V ne se trouve
pas dans le tableau".

EXERCICE 3
Ecrire un programme qui demande à l'utilisateur de saisir 10 entiers stockés dans un tableau. Le programme doit
ensuite afficher l'indice du plus grand élément.

EXERCICE 4
Ecrire un programme qui demande à l'utilisateur de saisir 10 entiers stockés dans un tableau ainsi qu'un entier V. Le
programme doit rechercher si V se trouve dans le tableau et doit supprimer la première occurence de V en décalant
d'une case vers la gauche les éléments suivants et en rajoutant un 0 à la fin du tableau. Le programme doit ensuite
afficher le tableau final.

EXERCICE 5
Ecrire un programme qui demande à l'utilisateur de saisir 10 entiers stockés dans un tableau ainsi qu'un entier V et
un entier i compris entre 0 et 9. Le programme doit décaler d'une case vers la droite tous les élements à partir de
l'indice i (en supprimant le dernier élément du tableau) et doit mettre la valeur V dans le tableau à l'indice i. Le
programme doit ensuite afficher le tableau final.

EXERCICE 6
Ecrire un programme qui demande à l’utilisateur de taper 10 entiers qui seront stockés dans un tableau. Le
programme doit ensuite afficher soit "le tableau est croissant", soit "le tableau est décroissant", soit "le tableau est
constant", soit "le tableau est quelconque".

EXERCICE 7
Ecrire un programme qui demande à l’utilisateur de taper 10 entiers qui seront stockés dans un tableau. Le
programme doit trier le tableau par ordre croissant et doit afficher le tableau.
Algorithme suggéré :
On cherche l'indice du plus petit élément parmi les indices de 0 à 9 et on échange cet élément avec t[0].
On cherche l'indice du plus petit élément parmi les indices de 1 à 9 et on échange cet élément avec t[1].
On cherche l'indice du plus petit élément parmi les indices de 2 à 9 et on échange cet élément avec t[2].
On cherche l'indice du plus petit élément parmi les indices de 8 à 9 et on échange cet élément avec t[8].

EXERCICE 8
Ecrire un programme qui demande à l’utilisateur de taper 10 entiers qui seront stockés dans un tableau. Le
programme doit trier le tableau par ordre croissant et doit afficher le tableau.
Algorithme suggéré (tri bulle) :
On parcourt le tableau en comparant t[0] et t[1] et en échangeant ces éléments s'ils ne sont pas dans le bon ordre.
on recommence le processus en comparant t[1] et t[2],... et ainsi de suite jusqu'à t[8] et t[9].
On compte lors de ce parcours le nombre d'échanges effectués.
On fait autant de parcours que nécessaire jusqu'à ce que le nombre d'échanges soit nul : le tableau sera alors trié.
Programmation C++ (débutant)/Les tableaux statiques 12

EXERCICE 9
Ecrire un programme qui saisit 2 tableaux de 10 entiers a et b. c est un tableau de 20 entiers. Le programme doit
mettre dans c la fusion des tableaux a et b. On copiera dans les 10 premières cases de c le tableau a, dans les dix
dernières le tableau b. Le programme affiche ensuite le tableau c.

EXERCICE 10
Ecrire un programme qui saisit 2 tableaux de 10 entiers a et b qui doivent être triés dans l'ordre croissant. Le
programme devra tout d'abord vérifier que les deux tableaux sont triés. Le tableau c est un tableau de 20 entiers. Le
programme doit mettre dans c la fusion des tableaux a et b. Le tableau c devra contenir les éléments de a et ceux de b
et devra être trié. Le programme affiche ensuite le tableau c.

EXERCICE 11
Ecrire un programme qui gère une liste d'entiers grâce au menu suivant :
1. Ajouter un entier
2. Afficher la liste des entiers
3. Supprimer le dernier entier de la liste.
4. Afficher la dernière note tapée
5. Quitter
Il y aura au maximum 10 entiers. Lorsqu'on rajoute un entier, il sera rajouté à la fin de la liste.

EXERCICE 12
Ecrire un programme qui gère une liste d'entiers grâce au menu suivant :
1. Ajouter un entier
2. Afficher la liste des entiers
3. Supprimer le premier entier ayant une valeur donnée.
4. Supprimer tous les entiers ayant une valeur donnée
5. Quitter
Il y aura au maximum 10 entiers. La liste devra être en permanence triée : lorqu'on rajoute un entier, il sera inséré au
bon endroit dans la liste pour que celle-ci reste triée.

EXERCICE 13
Ecrire un programme qui demande à l'utilisateur de taper un entier N<=20 et qui affiche la N-ième ligne du triangle
de pascal.
ligne 1 : 1 1
ligne 2 : 1 2 1
ligne 3 : 1 3 3 1
ligne 4 : 1 4 6 4 1
et ainsi de suite ...
Programmation C++ (débutant)/Les tableaux statiques 13

EXERCICE 14
Ecrire un programme qui demande à l'utilisateur de taper 10 entiers compris entre 0 et 20 qui seront stockés dans un
tableau et qui affiche le nombre de fois qu'on a tapé un 0, le nombre de 1, le nombre de 2, ..., le nombre de 20.

EXERCICE 15
Ecrire un programme qui demande à l'utilisateur de taper le contenu d'un tableau de réels de 3 lignes et 3 colonnes et
qui affiche ce tableau mais en affichant la moyenne des éléments de chaque ligne, de chaque colonne et la moyenne
globale.
Programmation C++ (débutant)/Les fonctions 1

Programmation C++ (débutant)/Les fonctions


Le cours sur les fonctions

Pourquoi écrire des fonctions


Lorsqu'on a un ensemble de lignes de code qui doivent être exécutées à différents endroits dans un programme, au
lieu de réécrire les mêmes lignes de code, il est intéressant de créer des fonctions.
Au lieu d'écrire une fonction main() de 500 lignes, il est préférable de créer 25 fonctions de 20 lignes
• on structure le programme.
• il est plus facile de tester chaque fonction.
Il est impossible d'avoir en tête plus de 1000 lignes de codes : or la plupart des programmes réels comportent des
dizaines de milliers de lignes et les grosses applications en comportent des millions. Ecrire des fonctions est
absolument obligatoire.

Ecrire une fonction


Syntaxe : type identificateur(paramètres) { Corps de la fonction }
A chaque appel de la fonction on exécute le corps de la fonction.
L'identificateur est le nom de la fonction.
La fonction peut avoir des paramètres.
La fonction peut renvoyer une valeur de type type.

Appel à une fonction


Lors de l'appel de la fonction, le programme exécute la totalité des instructions du corps de la fonction, puis reprend
le programme juste après l'appel de la fonction.

Exemple 1 : un exemple de fonction


#include <iostream>
using namespace std;

void b()
{
cout<<"Bonjour"<<endl;
}

int main()
{
cout<<"COUCOU1"<<endl;
b();
cout<<"COUCOU2"<<endl;
b();
b();
cout<<"COUCOU3"<<endl;
b();
return 0;
}
Programmation C++ (débutant)/Les fonctions 2

• Explications
• Dans ce programme, on a créé une fonction b qui se contente d'afficher "Bonjour" à l'écran. La fonction b est
précédée du type void : cela signifie que la fonction ne renvoie aucune valeur au programme appelant.
• Le programme principal (la fonction main()) affiche "COUCOU1" à l'écran, ensuite appelle la fonction b,
affiche le message "COUCOU2" à l'écran, appelle ensuite 2 fois la fonction b, affiche le message
"COUCOU3" et appelle une dernière fois la fonction b.
• Exécution de l'exemple 1
Lorsqu'on exécute le programme voici ce qu'on obtient à l'écran :

COUCOU1
Bonjour
COUCOU2
Bonjour
Bonjour
COUCOU3
Bonjour

Les paramètres
On peut paramétrer une fonction : les paramètres permettent de rendre la fonction plus générale donc plus facilement
réutilisable. La réutilisation de code est une des notions fondamentales du langage C++. La notion de fonction est
une des premières méthodes nous permettant d'aborder le sujet.

Exemple 2 : une fonction avec des paramètres


#include <iostream>
using namespace std;

void b(int i)
{
int j;
for(j=0; j<i; j++) cout<<"Bonjour"<<endl;
}

int main()
{
cout<<"COUCOU1"<<endl;
b(2);
cout<<"COUCOU2"<<endl;
b(3);
return 0;
}

• Explications
• Cette fois-ci la fonction b comporte un paramètre entier i. Cette fonction affiche i fois "Bonjour" à l'écran.
• Dans le programme principal, la fonction main() affiche "COUCOU1", appelle ensuite la fonction b avec
comme paramètre 2, **Lors de l'appel b(2) de la fonction, on recopie la valeur 2 dans i puis on exécute le
corps de la fonction avec cette valeur de i : on affiche donc 2 fois "Bonjour".
Programmation C++ (débutant)/Les fonctions 3

• Lors de l'appel b(3) de la fonction, on recopie la valeur 3 dans i puis on exécute le corps de la fonction avec
cette valeur de i : on affiche donc 3 fois "Bonjour".
• Exécution
Lorsqu'on exécute le programme voici ce qu'on obtient à l'écran :

COUCOU1
Bonjour
Bonjour
COUCOU2
Bonjour
Bonjour
Bonjour

Environnement d'une fonction


• Une fonction peut avoir ses propres variables locales.
• On appelle environnement d'une fonction l'ensemble des variables accessibles dans le corps de la fonction.
• Il est possible de définir des variables globales (voir la définition des constantes) : il est fortement déconseillé
d'utiliser des variables globales autres que des constantes.
• L'environnement d'une fonction comprend :
• les variables locales à la fonction.
• les paramètres de la fonction.
• les variables globales.

Une fonction qui renvoie une valeur


Une fonction peut renvoyer une valeur d'un certain type à l'environnement appelant.
void signifie que la fonction ne renvoie rien. Si on veut que la fonction renvoie une certaine valeur, il faudra écrire
un autre type à la place de void.
Le mot clé return permet :
• d'arrêter l'exécution de la fonction (il est en général placé à la fin de la fonction)
• de renvoyer une valeur à l'environnement appelant.
Si une fonction b renvoie un entier, l'appel s'écrira : a=b(…); a permettra de récupérer la valeur renvoyée par le
return.

Exemple 3 : une fonction qui renvoie une valeur


#include<iostream>
using namespace std;

int b(int i, int j)


{

int k;
k = i*i + j*j;
return k;
}
Programmation C++ (débutant)/Les fonctions 4

int main()
{
int a;
a = b(3,4);
cout<<"Le resultat vaut : "<<a<<endl;
return 0;
}

• Explications
Lors de l'appel a=b(3,4);

• 3 et 4 sont respectivement recopiés dans les variables i et j.


• On exécute le corps de la fonction (qui contient une variable locale k)
• return k permet d'arrêter l'exécution de la fonction en renvoyant la valeur de k qui est recopiée dans a.
• L'environnement de la fonction main ne comprend que la variable a : on ne peut pas utiliser les variables i, j et
k dans la fonction main.
• L'environnement de la fonction b comprend les variables i,j et k : on ne peut pas utiliser a dans la fonction b.
• La séparation des environnements permet de mieux structurer les applications.
• Exécution :
Lorsqu'on exécute le programme voici ce qu'on obtient à l'écran :
Le resultat vaut : 25

Exemple 4 : une autre fonction


#include <iostream>
using namespace std;

int b(int i)
{
int k, s=0;
for(k=1; k<=i; k++) s = s+k*k;
return s;
}

int main()
{
int a;
a = b(4);
cout<<"Le résultat vaut :"<<a<<endl;
return 0;
}

• Explications
• On définit une fonction b qui a un paramètre entier i et qui calcule la somme des carrés des i premiers entiers.
• Dans la fonction main, on appelle b(4) et on récupère la valeur renvoye dans la variable a. a contient donc la
somme des 4 premiers carrés.
• Exécution
Lorsqu'on exécute le programme voici ce qu'on obtient à l'écran :
Le résultat vaut : 30
Programmation C++ (débutant)/Les fonctions 5

Exemple 5 : une fonction manipulant des réels


#include<iostream>
using namespace std;

double b(double x, double y)


{
double m;
m = (x+y) / 2;
return m;
}

int main()
{
double a;
a = b(3.2, 4.2);
cout<<"Le résultat vaut :"<<a<<endl;
return 0;
}

• Explications :
• Dans cette exemple, la fonction b a 2 paramètres de type double, nommées x et y. La fonction b renvoie un
double. Cette fonction renvoie la moyenne de x et de y. La variable m est une variable locale à la fonction b.
• Dans le programme principal, on récupère dans a la moyenne de 3.2 et 4.2 en appelant la fonction b.
• Exécution :
Lorsqu'on exécute le programme voici ce qu'on obtient à l'écran :
Le résultat vaut : 3.7

Compatibilité des types


Une fonction peut avoir des paramètres de différents types. Lors de l'appel, il convient de respecter l'ordre et le type
des paramètres entre l'entête et le corps de la fonction.

Passage de tableaux en paramètres


Lorsqu'on passe un tableau (d'entiers par exemple en paramètre), il y a identification entre le tableau de
l'environnement appelant et le paramètre de la fonction. Toute modification du tableau dans la fonction est
répercutée dans le tableau de l'environnement appelant.

Exemple 6 : passage de tableaux en paramètre


#include <iostream>
using namespace std;

const int n=4;

void saisir(int t[n])


{
int i;
for(i=0; i<n; i++)
Programmation C++ (débutant)/Les fonctions 6

{
cout<<"Tapez la valeur numero "<<i<<" : ";
cin >> t[i];
}
}

void affiche(int t[n])


{
int i;
for(i=0; i<n; i++) cout<<"La valeur numero "<<i<<" est : "<<t[i]<<endl;
}

int main()
{
int a[n];
saisir(a);
affiche(a);
return 0;
}

• Explications
• Lors de l'appel saisir(a), il y a identification du tableau a et du paramètre t de la fonction saisir : toute
modification de t modifie le tableau a. La fonction saisir a permet de demander à l'utilisateur de saisir une à
une toutes les cases d'un tableau de n cases.
• La fonction affiche à un tableau de n entiers en paramètres et affiche toutes les cases de ce tableau.
• Le programme est structuré : il est constitué d'un ensemble de fonctions courtes dont le rôle peut être
facilement identifié.
• Le main() devient un programme très court !
• Exécution
Lorsqu'on exécute le programme voici ce qu'on obtient à l'écran :

Tapez la valeur numero 0 : 4


Tapez la valeur numero 1 : 6
Tapez la valeur numero 2 : 5
Tapez la valeur numero 3 : 7
La valeur numero 0 est : 4
La valeur numero 1 est : 6
La valeur numero 2 est : 5
La valeur numero 3 est : 7
Programmation C++ (débutant)/Les fonctions 7

Attention
Une modification d'un paramètre qui n'est pas un tableau dans le corps d'une fonction n'est pas répercuté dans
l'environnement appelant.

Exemple 7
#include <iostream>
using namespace std;

void saisir(int n)
{
cout<<"Tapez un entier : "; cin>>n;
}

void affiche(int n)
{
cout<<"La valeur de l'entier est : "<<n<<endl;
}

int main()
{
int x;
x=54;
saisir(x);
affiche(x);
return 0;
}

• Explications
• Dans la fonction main, on définit une variable entière x et on l'initialise à 54.
• On appelle ensuite la fonction saisir : on copie la valeur de x dans n. Dans le corps de la fonction saisir, on
demande à l'utilisateur de taper une valeur qui est mise dans x. Mais à aucun moment cette valeur x n'est mise
dans la variable x : la valeur tapée par l'utilisateur est donc perdue.
• La valeur de x reste donc à 54. Lorsqu'on appelle la fonction affiche, on affiche la valeur 54.
• Exécution
Lorsqu'on exécute le programme voici ce qu'on obtient à l'écran :
Tapez un entier : 20
La valeur de l'entier : 54
Programmation C++ (débutant)/Les fonctions 8

Passage de paramètres par référence


On peut passer un paramètre par référence (et non par copie) en indiquant dans l'entête de la fonction un & après le
type. Il y a alors identification du paramètre de la fonction et de la variable de l'environnement appelant.

Exemple 8 : passage de paramètres par référence


#include <iostream>
using namespace std;

void saisir(int & n)


{
cout<<"Tapez un entier : "; cin>>n;
}

void affiche(int n)
{
cout<<"La valeur de l'entier : "<<n<<endl;
}

int main()
{
int x;
x=54;
saisir(x);
affiche(x);
return 0;
}

• Explications
• Lors de l'appel saisir(x), il y a identification des variables x et n : toute modification de n modifie la valeur de
x. Lorsque l'utilisateur saisit la valeur de n dans l'instruction cin>>n; , il y a modification du contenu de la
variable x. On récupère dans x la valeur tapée par l'utilisateur
• On appelle ensuite la fonction affiche qui affiche la valeur de x.
• Exécution
Lorsqu'on exécute le programme voici ce qu'on obtient à l'écran :
Tapez un entier : 20
La valeur de l'entier: 20
Programmation C++ (débutant)/Les fonctions 9

Paramètres en entrées et en sorties


• Certains paramètres vont fournir des données à une fonction : les paramètres en entrée.
• D'autres vont permettre de renvoyer une valeur vers l'environnement appelant : les paramètres en sortie.
• Techniquement , on utilisera le return ou le passage de paramètres par référence pour envoyer une valeur à
l'environnement appelant.
• D'autres peuvent éventuellement avoir les 2 rôles : les paramètres en entrée/sortie.

Exemple 9 : paramètres en entrées et en sorties


#include <iostream>
using namespace std;

void minmax(int i, int j, int & min, int & max)


{
if(i<j) {min=i; max=j;} else {min=j; max=i;};
}

int main()
{
int a,b,w, x;

cout << "Tapez la valeur de a : "; cin >> a;


cout << "Tapez la valeur de b : "; cin >> b;
minmax(a,b,w,x);
cout << "Le plus petit vaut : " << w << endl;
cout << "Le plus grand vaut : " << x << endl;
return 0;
}

• Explications
• La fonction minmax permet de récupérer le plus petit et le plus grand de 2 entiers i et j.
• Dans la fonction minmax, i et j sont les paramètres en entrée et min et max sont les paramètres en sorties.
• Dans le main, lorsqu'on appelle la fonction minmax, on recopie les valeurs de a et de b respectivement dans i et
j et il y a identification des variables w et min et des variables x et max durant toute la durée de l'appel de la
fonction.
• Dans w on récupère donc le plus petit de a et de b et dans x le plus grand de a et de b.
• Exécution
Lorsqu'on exécute le programme voici ce qu'on obtient à l'écran :
Tapez la valeur de a : 15
La valeur de b est : 11
Le plus petit vaut 11
Le plus grand vaut 15
Programmation C++ (débutant)/Les fonctions 10

Passer un tableau de taille quelconque


• Le paramètre d'une fonction peut être un tableau de taille quelconque.
• Dans l'environnement appelant, la taille du tableau devra être déterminée.
• En général, lorsqu'on passe un tableau de taille quelconque, on passe un autre paramètre entier qui indique la taille
du tableau.

Exemple 10 : passer un tableau de taille quelconque


#include <iostream>
using namespace std;

void saisir(int t[], int n)


{
int i;
for(i=0; i<n; i++)
{
cout << "Tapez l'entier numero " << i << " : ";
cin >> t[i];
}
}

void afficher(int t[], int n)


{
int i;
for(i=0; i<n; i++)
cout << "L'entier numero " << i << " vaut : " << t[i] << endl;
}

int main()
{
int a[3], b[5];
cout << "SAISIE DU TABLEAU a" << endl;
saisir(a, 3);
cout << "SAISIE DU TABLEAU b" << endl;
saisir(b, 5);
cout << "AFFICHAGE DU TABLEAU a" << endl;
afficher(a, 3);
cout << "AFFICHAGE DU TABLEAU b" << endl;
afficher(b, 5);
return 0;
}

• Explications
• Dans la fonction saisir, le premier paramètre est int t[] : il s'agit donc d'un tableau d'entiers de n'importe quelle
taille. Le deuxième paramètre n indique la taille du tableau. Cette fonction demande à l'utilisateur de saisir une
à une toutes les cases du tableau.
• La fonction affiche a également comme paramètres un tableau d'entiers de taille quelconque et un paramètre n
qui indique la taille du tableau. Cette fonction affiche le contenu du tableau.
Programmation C++ (débutant)/Les fonctions 11

• Dans le programme principal, on saisit le contenu du tableau a contenant 3 cases et du tableau b contenant 5
cases en ** On constate toutefois que dans la fonction main, la taille des tableaux a et b est belle et bien
connue.
• Exécution
Lorsqu'on exécute le programme voici ce qu'on obtient à l'écran :

SAISIE DU TABLEAU a
Tapez l'entier numero 0: '''123'''
Tapez l'entier numero 1: '''456'''
Tapez l'entier numero 2: '''789'''
SAISIE DU TABLEAU b
Tapez l'entier numero 0: '''987'''
Tapez l'entier numero 1: '''654'''
Tapez l'entier numero 2: '''321'''
Tapez l'entier numero 3: '''741'''
Tapez l'entier numero 4: '''852'''
AFFICHAGE DU TABLEAU a
L'entier 0 vaut : 123
L'entier 1 vaut : 456
L'entier 2 vaut : 789
AFFICHAGE DU TABLEAU b
L'entier 0 vaut : 987
L'entier 1 vaut : 654
L'entier 2 vaut : 321
L'entier 3 vaut : 741
L'entier 4 vaut : 852

Portée des variables


• Dans le main, on peut accéder :
• aux variables locales du main
• aux constantes globales
• Dans une fonction, on peut accéder
• aux paramètres de la fonction
• aux constantes globales
• Il est déconseillé de définir des variables globales non constantes !
• Les échanges entre les environnements se font :
• par les returns
• par les passages de paramètres par référence
Programmation C++ (débutant)/Les fonctions 12

Conclusion
• Il faudra maîtriser les passages de paramètres par valeur et par référence ainsi que le rôle particulier des tableaux.
• Il est indispensable d'avoir bien compris le rôle des paramètres en entrée et en sortie d'une fonction.
• Les fonctions vont jouer un rôle fondamental dans la structuration de nos programmes. Nos programmes vont
maintenant être constitués d'une multitude de fonctions qui auront une taille petite (10 à 30 lignes) et qui auront
toutes un rôle très précis.
• Cette méthodologie est indispensable pour créer de longs programmes.

Exercices sur les fonctions

EXERCICE 1
Ecrire une fonction distance ayant comme paramètres 4 doubles xa,ya et xb,yb qui réprésentent les coordonnées de
deux points A et B et qui renvoie la distance AB. Tester cette fonction.

EXERCICE 2
Ecrire une fonction f ayant comme paramètres un double x et un booléen ok et qui renvoie un double par un return.
La fonction renvoie par un return la racine carrée de (x-1)*(2-x). La fonction renvoie par l'intermédiaire de la
variable ok la valeur true si la fonction est définie au point x, false sinon. Tester cette fonction.

EXERCICE 3
Ecrire une fonction f ayant en paramètre un entier et qui renvoie par un return un booléen : true si l'entier est premier
et false sinon. Tester cette fonction.

EXERCICE 4
Ecrire une fonction f ayant comme paramètre un entier n et qui renvoie le n-ième nombre premier : cette fonction
utilisera la fonction du 3). Tester cette fonction.

EXERCICE 5
Ecrire une fonction swap ayant en paramètres 2 entiers a et b et qui echange les contenus de a et de b. Tester cette
fonction.

EXERCICE 6
Ecrire une fonction f ayant en paramètres un tableau t de taille quelconque et un entier n indiquant la taille du
tableau. f doit renvoyer par un return un booleén b indiquant s'il existe une valeur comprise entre 0 et 10 dans les n
premières cases du tableau t. Tester cette fonction.

EXERCICE 7
Ecrire une fonction f ayant en paramètres un tableau t de taille quelconque et un entier n indiquant la taille du
tableau. f doit renvoyer par un return le nombre de valeurs comprises entre 0 et 10 dans les n premières cases du
tableau [Link] cette fonction.
Programmation C++ (débutant)/Les fonctions 13

EXERCICE 8
Ecrire une fonction f ayant en paramètres un tableau t de taille quelconque et un entier n indiquant la taille du
tableau. f possède un autre paramètre v , entier passé par référence. f doit renvoyer par un return un booleén b
indiquant s'il existe une valeur comprise entre 0 et 10 dans les n premières cases du tableau t. Si f renvoie true, v est
égal à la valeur de la première case du tableau comprise entre 0 et 10. Tester cette fonction.

EXERCICE 9
Ecrire une fonction f ayant en paramètres un tableau t1 de taille quelconque et un entier n indiquant la taille du
tableau, ainsi qu'un tableau t2 de la même taille que t1. f doit renvoyer par un return un entier nb indiquant le nombre
de valeurs comprises entre 0 et 10 dans le tableau t1. f doit mettre dans le tableau t2 les différentes valeurs comprise
entre 0 et 10 qu'il a rencontrées dans le tableau t1.

EXERCICE 10
Ecrire une fonction f ayant en paramètres un tableau t de taille quelconque et un entier n indiquant la taille du
tableau. f doit renvoyer par un return un entier égal à l'indice de la première case du tableau (parmi les n premières)
comprise entre 0 et 10. S'il n'existe pas de telle valeur, la fonction renvoie -1. Tester cette fonction.
Sources et contributeurs de l’article 14

Sources et contributeurs de l’article


Programmation C++ (débutant)/Les fonctions Source: [Link] Contributeurs: Adniang75, JackPotte, Merrheim, Tavernier, Trefleur, 28
modifications anonymes

Licence
Creative Commons Attribution-Share Alike 3.0 Unported
http:/ / creativecommons. org/ licenses/ by-sa/ 3. 0/
Programmation C++ (débutant)/Les tableaux de char 1

Programmation C++ (débutant)/Les tableaux de


char
Avant-propos important
Lorsqu'on étudie le C++ faut-il étudier d'abord la classe string ou d'abord les tableaux de char ?
Dans ce cours, nous étudierons en premier les tableaux de char, fidèle à notre pédagogie ascendante : nous partons
des entités les plus rudimentaires pour construire petit à petit des entités de haut niveau. Ce n'est que dans plusieurs
chapitres que nous présenterons la classe string.
Ce choix pédagogique est largement assumé dans ce livre mais il suscite en général une controverse assez vive.
Qui détient la vérité en matière de pédagogie ? Il serait bon d'ailleurs que ceux qui sont opposés à ce choix proposent
un autre livre : "Le C++ pour débutants avec une pédagogie descendante."
Il serait très intéressant de pouvoir comparer les différentes stratégies pédagogiques.

Le cours du chapitre 8 : les tableaux de char

string ou tableaux de char


En C++, il existe plusieurs façons de représenter les chaînes de caractères : on peut utiliser la classe prédéfinie string
ou on peut utiliser des tableaux de char. On parle alors parfois de chaîne de caractères de style C.
Pour des raisons pédagogiques qui nous semblent fondamentales, nous allons étudier les chaînes de caractères
représentées par des tableaux de char.
Ceci nous permettra de mettre en évidence les insuffisances de cette représentation et pourquoi il est largement
préférable d'utiliser la classe string. Il faut avoir en tête que la classe string fait appel à des notions finalement très
complexes (l'allocation dynamique de mémoire notamment, ou encore les pointeurs), même si son emploi est très
simple.

Chaînes de caractères de style C


Une telle chaîne de caractères est contenue dans un tableau de char. Chaque caractère sera dans une case du tableau.
A la fin d'une chaîne de caractères (qui n'est pas forcément à la dernière case du tableau) doit se trouver le caractère
spécial noté '\0' qui indique la fin de la chaîne.

Affichage et saisie d'une chaîne


On peut afficher une chaîne de caractères par cout : le tableau de caractères sera alors affiché jusqu'au caractère de
fin de chaîne.
On peut saisir une chaîne par cin : le caractère de fin de chaîne est alors rajouté automatiquement.
On peut accéder au caractère numéro i d'une chaîne t en indexant le tableau t[i].

Exemple 1 : affichage et saisie


Dans cet exemple, on déclare un tableau de 20 char noté tt : dans chaque case de 0 à 7 on place une lettre et dans la
case 8 on place le caractère de fin de chaîne.

#include <iostream>
using namespace std;

int main()
Programmation C++ (débutant)/Les tableaux de char 2

{
char tt[20];
tt[0] = 'B';
tt[1] = 'O';
tt[2] = 'N';
tt[3] = 'J';
tt[4] = 'O';
tt[5] = 'U';
tt[6] = 'R';
tt[7] = '\0';
cout << tt;
return 0;
}

• Explications
tt contient la chaîne de caractères "BONJOUR". Nous avons construit case par case cette chaîne ! En général, on
utilisera des fonctions prédéfinies nous permettant de faire cela ! On peut afficher cette chaîne par un simple cout.
Remarque : dans la pratique, on ne copiera JAMAIS lettre par lettre une chaîne dans un tableau.
• Exécution
Lorsqu'on exécute le programme voici ce qu'on obtient à l'écran :
BONJOUR

Exemple 2 : saisie d'une chaîne


#include <iostream>
using namespace std;

int main()
{
char tt[20];
cout << "Tapez une chaîne SVP : ";
cin >> tt;
cout << "Vous avez tapé la chaîne : ";
cout << tt << endl;
return 0;
}

• Explications
• On déclare un tableau de 20 char noté tt.
• On saisit une chaîne de caractères grâce à cin.
• On affiche alors la chaîne de caractères qu'on vient de taper par un cout.
• Exécution
Lorsqu'on exécute le programme voici ce qu'on obtient à l'écran :
Tapez une chaîne SVP : BONJOUR
Vous avez tapé la chaîne : BONJOUR
Remarque: le tableau tt est limité à 20 caractères. Cependant une entrée de 30 caractères les affiche aussi bien !! Où
est l'erreur ?
Programmation C++ (débutant)/Les tableaux de char 3

Manipulation de chaînes
Les chaînes de caractères sont contenues dans des tableaux de char, il existe de nombreuses fonctions prédéfinies
dans le fichier cstring qui permettent de manipuler simplement ces tableaux. Ainsi, on peut aisément copier,
comparer, transformer… des chaînes de caractères. Nous allons étudier quelques-unes de ces fonctions standard.

Comparaison de 2 chaînes
On ne teste pas l'égalité de 2 chaînes par ==, on utilise strcmp(chaine1,chaine2) qui renvoie :
0 si les 2 chaînes sont égales.
un nombre <0 si chaîne1 est avant chaîne2 dans l'ordre lexicographique.
un nombre >0 si chaîne1 est après chaîne2 dans l'ordre lexicographique.
Pour utiliser strcmp, il faut inclure cstring.

Exemple 3 : comparaison de 2 chaînes


#include <iostream>
#include <cstring>

using namespace std;

int main()
{
char tt[20];
cout << "Tapez une chaîne : "; cin >> tt;
if(strcmp(tt, "BONJOUR")==0)
cout<<"GAGNE"<<endl;
else cout<<"PERDU"<<endl;
return 0;
}

• Explications
• Dans cet exemple, on commence par demander à l'utilisateur de saisir une chaîne de caractères tt.
• Grâce à la fonction strcmp, on va comparer cette chaîne à la chaîne "BONJOUR".
• Si on a tapé la chaîne "BONJOUR", on affichera le message "GAGNE", sinon on affichera le message
"PERDU".
• Exécution 1
Lorsqu'on exécute le programme voici ce qu'on obtient à l'écran :
Tapez une chaîne : BONSOIR
PERDU
• Exécution 2
Lorsqu'on exécute le programme voici ce qu'on obtient à l'écran :
Tapez une chaîne : BONJOUR
GAGNE
Programmation C++ (débutant)/Les tableaux de char 4

Exemple 4 : ordre lexicographique


#include <iostream>
#include <cstring>

using namespace std;

int main()
{
char a[20];
cout << "Tapez une chaîne : "; cin >> a;
if (strcmp(a,"BONJOUR")>0)
cout << a << " est après BONJOUR" << endl;
else
cout << a << " est avant BONJOUR" << endl;
return 0;
}

• Explications
• Dans cet exemple, on demande à l'utilisateur de saisir une chaîne de caractères a.
• On compare ensuite cette chaîne à la chaîne de caractères "BONJOUR".
• Si la chaîne tapée se trouve avant "BONJOUR" dans l'ordre lexicographique, on affiche un message indiquant
que la chaîne se trouve avant "BONJOUR".
• Si la chaîne se trouve après "BONJOUR", on affiche un message similaire.
• Exécution 1
Lorsqu'on exécute le programme voici ce qu'on obtient à l'écran :
Tapez une chaîne : AAA
AAA est avant BONJOUR
• Exécution 2
Lorsqu'on exécute le programme voici ce qu'on obtient à l'écran :
Tapez une chaîne : ZZZ
ZZZ est après BONJOUR

Copie d'une chaîne


On n'utilise pas l'affectation pour copier une chaîne dans une autre.
On utilise strcpy(chaine1,chaine2) qui copie la deuxième chaîne dans la première.

Exemple 5
#include <iostream>
#include <cstring>

using namespace std;

int main()
{
char a[20], b[20];
strcpy(a, "BONJOUR");
Programmation C++ (débutant)/Les tableaux de char 5

strcpy(b, a);
cout << "La chaîne b vaut : " << b << endl;
return 0;
}

• Explications
• Dans cet exemple, on déclare 2 chaînes de caractères a et b.
• On copie la chaîne "BONJOUR" dans a en utilisant strcpy.
• On copie ensuite la chaîne a dans la chaîne b toujours en utilisant strcpy.
• On affiche ensuite la chaîne b.
• Exécution
Lorsqu'on exécute le programme voici ce qu'on obtient à l'écran :
La chaîne b vaut BONJOUR

Longueur d'une chaîne


• La fonction strlen permet de connaître le nombre de caractères d'une chaîne.
• On ne tient pas compte du caractère de fin de chaîne lorsqu'on compte les caractères.

Exemple 6 : longueur d'une chaîne


#include <iostream>
#include <cstring>

using namespace std;

int main()
{
char a[20];
int b;
cout << "Tapez une chaîne : "; cin >> a;
b = strlen(a);
cout << "Taille de la chaine = " << b << endl;

return 0;
}

• Explications
• Dans cet exemple on déclare une chaîne de caractères a et un entier b.
• On demande à l'utilisateur de saisir la chaîne a au clavier.
• Dans l'entier b, on calcule la longueur de la chaîne a en utilisant la fonction strlen.
• On affiche par un cout la valeur de b.
• Exécution
Lorsqu'on exécute le programme voici ce qu'on obtient à l'écran :
Tapez une chaîne : BONJOUR
Taille de la chaîne=7
Programmation C++ (débutant)/Les tableaux de char 6

Validation d'une donnée saisie


Lorsqu'on saisit une chaîne de caractères, l'utilisateur peut toujours taper autre chose que ce qui était demandé : par
exemple, on demande à l'utilisateur de taper une heure sous un certain format. Il faut vérifier que l'utilisateur a bien
tapé une donnée correcte et lui demander de la retaper s'il s'est trompé.

Exemple 7 : validation d'une "heure"


#include <iostream>

using namespace std;

bool valide(char t[])


{
bool r=true;
int h,m;
if( t[0]<'0' ||t[0]>'9')
r=false;
else if( t[1]<'0' ||t[1]>'9')
r=false;
else if( t[3]<'0' ||t[3]>'9')
r=false;
else if( t[4]<'0' ||t[4]>'9')
r=false;
else if(t[2]!='h')
r=false;
else if(t[5]!='\0')
r=false;
else { h=(t[0]-'0')*10+(t[1]-'0');
if(h>23)r=false; m=(t[3]-'0')*10+(t[4]-'0');
if(m>59)r=false; }

return r;
}

int main()
{
char a[20];
do {
cout << "Tapez une heure sous le format ..h.. : ";
cin >> a;
} while (!valide(a));
return 0;
}

• Explications
La fonction valide a comme paramètre une chaîne de caractères et renvoie le booléen true si la chaîne passée en
paramètre est une heure valide et renvoie false sinon.
Pour tester si notre chaîne est valide, il faut :
Programmation C++ (débutant)/Les tableaux de char 7

vérifier que les caractères 0, 1, 3 et 4 sont bien des chiffres.


vérifier que le caractère 2 est bien le caractère 'h'.
vérifier que le caractère 5 est bien le caractère de fin de chaîne '\0'.
calculer dans h le nombre d'heures et vérifier que h est inférieur ou égal à 23.
calculer dans m le nombre de minutes et vérifier que m est bien inférieur ou égal à 59.
Si une de ces conditions n'est pas vérifiée, la chaîne ne sera pas valide.
Dans le programme principal, on saisit une chaîne de caractères au clavier.
Tant que la chaîne tapée ne sera pas une heure qui correspond au format imposé, alors on demandera à l'utilisateur de
saisir à nouveau une nouvelle chaîne.
• Exécution
Lorsqu'on exécute le programme voici ce qu'on obtient à l'écran :
Tapez une heure sous le format ..h.. : aze
Tapez une heure sous le format ..h.. : 12h50h
Tapez une heure sous le format ..h.. : 25h98
Tapez une heure sous le format ..h.. : 12h06

Séparateurs
Par défaut le caractère indiquant la fin d'une chaîne en cours de saisie est l'espace ou le retour chariot. Cela empêche
de saisir une chaîne comportant un espace.
[Link](…) permet de saisir une chaîne pouvant comporter des espaces : seul le retour chariot –touche «entrée»)
fait alors office de séparateur. On peut également tronquer la chaîne en indiquant la taille du tableau contenant cette
chaîne.

Exemple 8 : saisie d'une chaîne avec espaces


#include <iostream>

using namespace std;

int main()
{
char tt[10];
cout << "Tapez une chaîne SVP : "; [Link](tt,10);
cout << "Vous avez tapé la chaîne : ";
cout << tt << endl;
return 0;
}

• Explication
• Dans cet exemple, nous définissons une chaîne de caractères notées tt.
• On saisit au clavier une chaîne de caractères pouvant contenir des espaces et qui doit être contenue dans un
tableau de 10 char (elle comportera 9 caractères utiles au maximum plus le caractère de fin de chaîne) : elle
sera automatiquement tronquée en conséquence.
• On affiche ensuite la chaîne que l'utilisateur vient de taper. Elle sera éventuellement tronquée.
• Exécution 1
Lorsqu'on exécute le programme voici ce qu'on obtient à l'écran :
Tapez une chaîne SVP : azer ty
Programmation C++ (débutant)/Les tableaux de char 8

Vous avez tapé la chaîne : azer ty


• Exécution 2
Lorsqu'on exécute le programme voici ce qu'on obtient à l'écran :
Tapez une chaîne SVP : aaaaaaaaaaaaa
Vous avez tapé la chaîne : aaaaaaaaa

Conclusion
Nous avons étudié comment les chaînes de caractères étaient représentées en C++. Nous avons vu quelques fonctions
prédéfinies permettant de manipuler ces chaînes. Nous avons vu comment il était possible de vérifier si une chaîne
de caractères était sous un certain format. Il nous reste maintenant à effectuer des exercices pour utiliser ces
fonctions et pour manipuler des chaînes de caractères en tout genre.

Exercices

EXERCICE 1
Ecrire une fonction qui a en paramètres une chaîne de caractères (paramètre en entrée) et un entier e (paramètre en
sortie). Cette fonction renvoie un booléen. La fonction renvoie true si la chaîne de caractères est un entier écrit sous
la forme d'une suite de chiffres qui ne commence pas par 0, elle renvoie false sinon. Si la chaîne est correcte, la
fonction renvoie dans e la valeur de cet entier.

EXERCICE 2
Ecrire une fonction qui a en paramètre une chaîne de caractères (paramètre en entrée et en sortie) et qui transforme
toutes les minuscules de la chaîne en majuscules.

EXERCICE 3
Ecrire une fonction qui a en paramètre une chaîne de caractères (paramètre en entrée et en sortie) et qui supprime
toutes les voyelles.

EXERCICE 4
Ecrire une fonction qui a en paramètres deux chaînes de caractères ch1 et ch2 (paramètres en entrée) et renvoie un
booléen indiquant si la chaîne ch2 est contenue dans la chaîne ch1.

EXERCICE 5
Ecrire un programme qui demande à l'utilisateur de taper un verbe du premier groupe et qui le conjugue à l'indicatif
présent.

EXERCICE 6
Ecrire un programme qui saisit une chaîne pouvant contenir des espaces et qui affiche chaque mot de la chaîne, le
séparateur étant l'espace.
Exemple, on tape : je pense donc je suis
Le programme affiche :
mot 1 : je
mot 2 : pense
mot 3 : donc
mot 4 : je
Programmation C++ (débutant)/Les tableaux de char 9

mot 5 : suis

EXERCICE 7
Ecrire un programme qui demande à l'utilisateur de taper une chaîne de caractères et qui indique si cette chaîne est
un palindrome ou non.

EXERCICE 8
Ecrire un programme qui demande à l'utilisateur de taper une chaîne de caractères et qui affiche la lettre (minuscule
ou majuscule) la plus fréquente.
Programmation C++ (débutant)/Les structures 1

Programmation C++ (débutant)/Les structures


Le cours sur les structures

Présentation
Nous avons utilisé pour l'instant des types de base : ils contiennent des éléments de type int, char, double ou
bool. Dans ce chapitre nous allons définir de nouveaux types qui vont permettre de représenter des entités plus
complexes. Par exemple, on pourra définir un type point qui contiendra une abscisse et une ordonnée. Nous allons
donc apprendre à créer et à utiliser des types structurés.
Nous verrons ensuite comment, à partir de ces types, nous pouvons créer des fonctions permettant de manipuler ces
nouveaux types. L'association de ces types et de ces fonctions sera appelée module, chacun sera défini par un fichier
d'en-tête .h et un fichier source .cpp. Nous verrons à cette occasion la compilation séparée. Notre programme ne
sera plus constitué d'un seul fichier mais d'un ensemble de fichiers qui pourra éventuellement être très important.
Nous étudierons finalement un type de structure très usuel : les listes. Dans ce chapitre, notre représentation des
listes sera très sommaire mais sera l'occasion de découvrir une méthodologie de programmation en découpant notre
programme en différents modules qui seront dans une certaine mesure indépendants. Cette méthodologie nous
permettra de concevoir des programmes de taille plus importante.

Idée
En général, pour représenter en C++ des données, il faut plusieurs variables.
Exemple :
- pour représenter un point, il faut une abscisse et une ordonnée.
- pour représenter une fraction, il faut un numérateur et un dénominateur .
- pour représenter une liste de notes, il faut un nombre de notes et un tableau d'entiers ...

Les structures
On va créer de nouveaux types qui regroupent plusieurs variables. D'apparence anodine, cette idée est extrêmement
puissante.
Exemple :

struct point
{
double x,y;
};

Variable de type structuré


On peut maintenant définir des variables de type point .
Par exemple :

point a , b;

a contient 2 réels appelés a.x et a.y.


L'abscisse du point a sera notée a.x.
a.x est de type double.
L'ordonnée du point b sera notée b.y, de type double également.
a.x et a.y peuvent être utilisés pour des affectations, des entrées-sorties, comme toute variable de type double.
Programmation C++ (débutant)/Les structures 2

Des données de plus en plus complexes


En fait, en définissant de nouveaux types, on crée des types de données plus complexes qui pourront eux-mêmes
donner naissance à des type de données encore plus complexes et ainsi de suite. Cette méthodologie permettra de
concevoir des types de données extrêmement élaborés (un texte structuré comme dans un traitement de texte par
exemple). Le programmeur finira par en oublier les différents champs les composant en ne retenant que les
manipulations qu'il est capable d'effectuer sur ces données.

Exemple 1 : le type point


#include<iostream>
using namespace std;

struct point
{
double x,y;
};

int main()
{
point a,b,c;

a.x=3.2;
a.y=6.4;

cout << "Tapez l'abscisse de b : ";


cin >> b.x;

cout << "Tapez l'ordonnée de b : ";


cin >> b.y;

c.x = (b.x + a.x) / 2;


c.y = (b.y + a.y) / 2;

cout << "Abscisse de c : " << c.x << endl;


cout << "Ordonnée de c : " << c.y << endl;

return 0;
}

• Explications
• Dans cet exemple, nous définissons une structure point composée de 2 réels x et y.
• Dans la fonction main, on définit 3 points a,b et c.
• On fixe les coordonnées du point a à (3.2,6.4).
• On demande à l'utilisateur de saisir les coordonnées du point b.
• On calcule dans c les coordonnées du milieu du segment [ab].
• On affiche finalement les coordonnées du point c.
• Exécution
Programmation C++ (débutant)/Les structures 3

Lorsqu'on exécute le programme voici ce qu'on obtient à l'écran :


Tapez l'abscisse de b : 5.8
Tapez l'ordonnée de b : 3.6
Abscisse de c : 4.5
Ordonnée de c : 5.0

Structuration d'un programme


• On va définir des structures.
• On va ensuite écrire des fonctions permettant de manipuler ces structures.
• On peut ensuite définir de nouvelles structures plus complexes à partir des structures de base et ainsi de suite.
• Cette approche de la programmation par les structures de données est une véritable méthodologie de structuration
du programme.

Fonctions manipulant des points


Sur le type point, on peut envisager d'effectuer les opérations suivantes :
• saisir les coordonnées d'un point au clavier.
• afficher les coordonnées d'un point.
• calculer la distance entre 2 points.
• calculer le milieu de 2 points.
• Nous allons donc créer 4 fonctions nous permettant d'effectuer des manipulations sur les points.

Exemple 2 : manipulation d'un point


#include<iostream>
using namespace std;
#include<cmath>

struct point
{
double x,y;
};

void saisir_point(point &p)


{
cout << "Tapez l'abscisse du point : "; cin >> p.x;
cout << "Tapez l'ordonnée du point : "; cin >> p.y;
}

void afficher_point(point p)
{
cout << "Abscisse du point : " << p.x << endl;
cout << "Ordonnée du point : " << p.y << endl;
}

double distance(point a, point b)


{
double dx,dy;
Programmation C++ (débutant)/Les structures 4

dx = a.x - b.x;
dy = a.y - b.y;
return sqrt( dx*dx + dy*dy );
}

void milieu(point a, point b, point &m)


{
m.x = (a.x + b.x) /2;
m.y = (a.y + b.y) /2;
}

int main()
{
point X,Y,Z;
double d;

cout << "SAISIE DE X" << endl;


saisir_point(X);

cout << "SAISIE DE Y" << endl;


saisir_point(Y);

d=distance(X,Y);
cout << "La distance de X à Y est : " << d << endl;

milieu(X,Y,Z);
cout << "AFFICHAGE DU POINT Z" << endl;
afficher_point(Z);

return 0;
}

• Explications
• Dans cet exemple, on définit une structure point.
• On définit une fonction saisir_point(&p) qui a en paramètre un point passé par référence : en effet, cette
fonction doit modifier la valeur du point p et y mettre les valeurs saisies par l'utilisateur. Il faut donc passer p
par référence. p est un paramètre en sortie de cette fonction.
• La fonction afficher_point(point p). Cette fonction affiche les coordonnées du point p. p est un paramètre en
entrée de cette fonction et il est inutile de le passer par référence.
• La fonction double distance(point a, point b) permet de calculer la distance entre les point a et b qui sont des
paramètres en entrée de cette fonction. La distance est renvoyée par un return.
• La fonction void milieu(point a, point b, point &m) calcule dans le point m le milieu du segment [ab]. a et b
sont des paramètres en entrée de cette fonction. m est un paramètre en sortie qui est passé par référence.
• La fonction main déclare 3 point X,Y et Z. On demande ensuite à l'utilisateur de taper les coordonnées de X et
Y. On calcule en appelant la fonction distance la distance entre X et Y. On calcule dans le point Z le milieu de
[XY]. On affiche finalement la distance XY et les coordonnées de Z.
• Exécution
Programmation C++ (débutant)/Les structures 5

Lorsqu'on exécute le programme voici ce qu'on obtient à l'écran :


SAISIE DE X :
Tapez l'abscisse du point : 3
Tapez l'ordonnée de a : 4
SAISIE DE Y
Tapez l'abscisse du point : 2
Tapez l'ordonnée de a : 5
La distance de X à Y est : 1.414
AFFICHAGE DU POINT Z
Abscisse du point : 2.5
Ordonnée du point : 4.5

Décomposition d'un programme en plusieurs fichiers


Nos programmes vont désormais être découpés en plusieurs fichiers : certains seront des fichiers d'en-tête et
porteront l'extension .h. D'autres comporteront du code et porteront l'extension .cpp.
Chaque programme sera constitué de modules : chaque module sera défini par un fichier .h et un fichier .cpp.
Chaque module aura une fonctionnalité bien définie. Il comportera en général la définition d'une structure et des
fonctions permettant de manipuler ces structures.
Cette approche nous permet d'améliorer petit à petit notre méthodologie de programmation.

Réécriture de l'exemple 2
• Nous allons réécrire l'exemple 2 en restructurant notre code selon cette approche modulaire.
• Nous allons définir un module point qui regroupera la définition d'un point et différentes manipulations sur les
points.
• Ce module sera réutilisable dans d'autres contextes.

Décomposition en modules
• On va créer un fichier point.h où on va regrouper :
• la structure point.
• les entêtes des fonctions manipulant point.
• On va écrire un fichier [Link] comportant :
• #include "point.h" .
• les fonctions manipulant des points.
On a ainsi créé un module réutilisable permettant de manipuler des points. Lorsque le programme principal voudra
utiliser notre module point, il faudra rajouter #include <point.h>.
Sur des petits programmes cette structuration semble être une perte de temps. En fait cela permet de gagner du temps
de débogage et cette méthodologie devient indispensable dès que l'application devient conséquente.
Programmation C++ (débutant)/Les structures 6

Le programme principal
Notre programme est désormais constitué de 3 fichiers :
• Les fichiers point.h et [Link] qui définissent un module point.
• Le fichier [Link] qui contient la fonction main. Ce fichier utilise le module point et commence donc par
#include "point.h".

Les fichiers d'en-tête


Un programme peut être constitué d'un grand nombre de modules : par exemple imaginons qu'un programme soit
constitué de 4 modules A, B, C et D.
On suppose que B et C utilisent les notions définies dans A : ils commencent donc tous les deux par
#include"A.h".
On suppose que le module D utilise les notions définies dans B et dans C. D commence donc par
#include"B.h" et #include"C.h".
Le module A sera donc défini 2 fois dans le module D une fois lors de l'inclusion de B.h et une deuxième fois lors
de l'inclusion de C.h. Le compilateur refusera de compiler notre programme !

Exemple 3 : programmation modulaire


Fichier point.h

#ifndef POINT_H
#define POINT_H

struct point
{
double x,y;
};

void saisir_point(point &p);


void afficher_point(point p);
double distance(point a, point b);
void milieu(point a, point b, point &m);

#endif

Fichier [Link]

#include "point.h"
#include <iostream>
#include <cmath>

using namespace std;

void saisir_point(point &p)


{
cout << "Tapez l'abscisse du point : "; cin >> p.x;
cout << "Tapez l'ordonnée du point : "; cin >> p.y;
}
Programmation C++ (débutant)/Les structures 7

void afficher_point(point p)
{
cout << "Abscisse du point : " << p.x << endl;
cout << "Ordonnée du point : " << p.y << endl;
}

double distance(point a, point b)


{
double dx,dy;
dx = a.x - b.x;
dy = a.y - b.y;
return sqrt( dx*dx + dy*dy );
}

void milieu(point a, point b, point &m)


{
m.x = (a.x + b.x) /2;
m.y = (a.y + b.y) /2;
}

Fichier [Link]

#include "point.h"
#include <iostream>

using namespace std;

int main()
{
point X,Y,Z;
double d;

cout << "SAISIE DE X" << endl;


saisir_point(X);

cout << "SAISIE DE Y" << endl;


saisir_point(Y);

d = distance(X,Y);
cout << "La distance de X à Y est : " << d << endl;

milieu(X,Y,Z);
cout << "AFFICHAGE DU POINT Z" << endl;
afficher_point(Z);

return 0;
}

• Explications
Programmation C++ (débutant)/Les structures 8

• Le fichier point.h va contenir :


• l'utilisation des directives #ifndef, #define et #endif pour éviter l'inclusion multiple des fichiers
.h.
• la définition de la structure point
• les entêtes des fonctions manipulant des points.
• Le fichier [Link] commence par #include "point.h". Comme il utilise cin et cout, il
contient aussi #include<iostream>. Comme il utilise la fonction sqrt, il contient aussi
#include<cmath>. Il contient également les 4 fonctions du module.
• Le fichier [Link] contient notre fonction main() qui est identique à celle de l'exemple 2.

Structuration de notre programme et de notre réflexion


• Au lieu d'avoir un seul grand fichier contenant le main et toutes les fonctions , il y a plusieurs petits fichiers .
• Lorsqu'on écrit le fichier point.h, on réfléchit à la spécification de chaque fonction : QUE fait notre fonction ?
• Lorsqu'on écrit le fichier [Link], on réfléchit à comment on implémente ces spécifications : COMMENT
RÉALISER cette fonctionnalité ?
• Lorsqu'on écrit notre fonction main, on réfléchit à l'utilisation des fonctions de point.h en vue de résoudre
notre programme : COMMENT UTILISER ces fonctions ?

Gérer une liste d'employés


On va maintenant réaliser un programme plus complexe : un service du personnel veut gérer des employés qui
possèdent chacun un nom, un prénom et un salaire. On veut manipuler une liste d'employés grâce au menu suivant :
1. Ajouter un employé
2. Afficher la liste
3. Rechercher un employé
4. Quitter

Cahier des charges


Le cahier des charges est un document écrit spécifiant avec la plus grande précision possible ce que doit faire notre
programme.
Un employé est défini par un nom, un prénom et un salaire. Le nom et le prénom comporteront au maximum 9
caractères utiles. Lorsqu'on rajoute un employé dans la liste, on le rajoute à la fin de la liste.
Lorsqu'on affiche la liste des employés, on l'affiche dans le même ordre que celui de la saisie.
Lorsqu'on recherche un employé, on saisit un nom, et on affiche toutes les caractéristiques de tous les employés
portant ce nom.

Analyse du problème
On réfléchit au problème et on définit un ensemble de structures de données et de fonctions permettant de répondre
au problème.
Il est bon de séparer les fonctions réalisant des entrées-sorties et les fonctions manipulant les données.
A la fin de cette analyse la structuration en modules de notre programme doit apparaître.

Résultat de notre réflexion


Dans notre programme, il y a 3 entités :
Un employé composé d'un nom, d'un prénom, et d'un salaire.
Une liste d'employés sur laquelle on peut ajouter un employé, afficher la liste et faire des recherches.
Une interface homme machine sous la forme de menu en mode texte.
Programmation C++ (débutant)/Les structures 9

Chacune de ces entités correspondra à un module.

Le module employé
Il contiendra la définition d'une structure employé.
Dans ce module, il y aura 2 fonctions : une pour saisir les caractéristiques d'un employé et une autre pour les afficher
à l'écran.

Le module liste
Notre liste d'employés sera représentée par un tableau statique de 100 employés et un entier nb qui représente le
nombre d'employés réellement présents dans la liste. On définira une telle structure dans ce module.
On définira également 4 fonctions pour manipuler cette liste :
• une fonction pour initialiser la liste à la liste vide.
• une fonction pour afficher une liste d'employés.
• une fonction pour ajouter un employé dans la liste.
• une fonction pour rechercher tous les employés portant un nom donné.
• Remarque : il y a de nombreuses méthodes pour représenter notre liste, nous en verrons une autre au chapitre
suivant.

Le module menu
Il permet de gérer notre interface graphique en mode texte. Il comporte :
• une fonction menu qui contient la boucle principale de notre menu.
• une fonction choix qui affiche le menu et saisit le choix de l'utilisateur.
• une fonction traiter_choix qui effectue la manipulation souhaitée par l'utilisateur sur la liste.

Exemple 4 : gérer une liste d'employés


Fichier emp.h

#ifndef EMP_H
#define EMP_H

struct employe
{
char nom[10];
char prenom[10];
double salaire;
};

void saisir_employe(employe &e);


//Permet de saisir un employé

void affiche_employe(employe e);


//Permet d'afficher un employé
#endif

Fichier [Link]
Programmation C++ (débutant)/Les structures 10

#include "emp.h"
#include <iostream>
using namespace std;

void saisir_employe(employe &e)


{
cout<<"Tapez le nom : "; cin>>[Link];
cout<<"Tapez le prenom : "; cin>>[Link];
cout<<"Tapez le salaire : "; cin>>[Link];
}

void affiche_employe(employe e)
{
cout<< [Link] <<" "<< [Link] <<" " << [Link] <<endl;
}

Fichier liste.h

#ifndef LISTE_H
#define LISTE_H

#include"emp.h"

const int liste_pleine=-1;


const int liste_nb_max=100;

struct liste
{
int nb;
employe t[liste_nb_max];
};

void init_liste(liste &l); //Initialise la liste à 0 employé


int ajoute(liste &l, employe e); // Ajoute en employé : renvoi -1 si le
tableau est plein 0 sinon
void affiche(liste l); // Affiche la liste
void recherche(liste l1, char nom[],liste &l2); // met dans l2 tous les
employés de l1 portant le nom nom
#endif

Fichier [Link]

#include "liste.h"
#include<iostream>
using namespace std;
#include<cstring>

void init_liste(liste &l)


{
Programmation C++ (débutant)/Les structures 11

[Link]=0;
}

int ajoute(liste &l, employe e)


{
int r;
if ([Link] == liste_nb_max) r = liste_pleine;
else { r=0; l.t[[Link]]=e; [Link]++; }
return r;
}

void affiche(liste l)
{
int i;
if([Link]==0) cout<<"LISTE VIDE"<<endl;
for(i=0; i<[Link]; i++) affiche_employe(l.t[i]);
}

void recherche(liste l1, char nom[],liste &l2)


{
int i;
init_liste(l2);
for(i=0; i<[Link]; i++) if(strcmp(l1.t[i].nom, nom)==0) ajoute(l2, l1.t[i]);
}

Fichier menu.h

#ifndef MENU_H
#define MENU_H
#include "liste.h"

void menu(liste &l);


int choix();
bool traiter_choix(liste &l,int choix);
#endif

Fichier [Link]

#include "menu.h"
#include <iostream>
using namespace std;

int choix()
{
int i;
cout << "[Link] un employe" << endl;
cout << "[Link] la liste" << endl;
cout << "[Link] un employe" << endl;
cout << "[Link]" << endl;
Programmation C++ (débutant)/Les structures 12

cout << "Votre choix :"; cin >> i;


return i;
}

void menu(liste &l)


{
bool fini;
int i;
do {
i = choix();
fini = traiter_choix(l, i);
}while(fini==false);
}

bool traiter_choix(liste &l,int choix)


{
employe e;
char nom[10];
liste l2;
int r;
bool fini = false;

switch(choix)
{
case 1:
saisir_employe(e);
r = ajoute(l, e);
if(r == liste_pleine) cout << "La liste est pleine" << endl;
break;

case 2:
affiche(l);
break;

case 3:
cout << "Tapez le nom :"; cin >> nom; recherche(l, nom, l2);
cout << "Voici le resultat de la recherche :" << endl;
affiche(l2);
break;

case 4:
fini = true;
break;
}
return fini;
}

Fichier [Link]
Programmation C++ (débutant)/Les structures 13

#include"liste.h"
#include"menu.h"
int main()
{
liste l;
init_liste(l);
menu(l);
return 0;
}

• Explications
• Notre programme sera constitué de 7 fichiers :
• emp.h et [Link] qui définissent notre module employé.
• liste.h et [Link] qui définissent notre module liste.
• menu.h et [Link] qui définissent notre module menu.
• La fichier [Link] qui contient notre programme fonction main().
• Un point technique
• Si l est une liste d'employé, le i-ième employé du tableau t de la liste l sera noté l.t[i] . Cet élément est du
type emp.
• Le salaire du i-ième employé du tableau t de la liste l sera noté l.t[i].salaire . Cet élément est du type double.
• Le nom du i-ième employé du tableau t sera noté l.t[i].nom . Il s'agit d'un tableau de char.
• Si on voulait accéder au j-ème caractère du nom du i-ième employé du tableau t de la liste l, il faudrait
écrire l.t[i].nom[j]
• Il ne faut pas se laisser impressionner par ces notations !
• le module employé
• La structure emp sera composé de 2 chaînes de caractères (le nom et le prénom) et d'un double (le salaire de
l'employé).
• La fonction void saisir_employe(employe &e) permet de saisir au clavier les caractéristique d'un employé :
employe est un paramètre en sortie de cette fonction.
• La fonction void affiche_employe(employe e) permet d'afficher à l'écran les caractéristiques d'un employé.
employe est un paramètre en entrée de cette fonction.
• le module liste
• La structure liste sera composée d'un tableau d'employés et d'un entier nb qui est le nombre d'employés
réellement ajoutés dans la liste. On peut définir des tableaux de structures de la même manière que
n'importe quelle autre tableau. La taille du tableau est défini par la constante liste_nb_max.
• La fonction void init_liste(liste &l) initialise la liste d'employés à la liste vide. Elle se contente de mettre à 0
le nombre d'employés.
• La fonction int ajoute(liste &l, employe e) ajoute l'employé e à la fin de la liste d'employés l. Cette fonction
renvoie 0 si tout s'est bien passé, elle renvoie liste_pleine si le tableau d'employés est plein.
• La fonction void affiche(liste l) affiche la liste d'employés à l'écran : cette fonction utilise la fonction
affiche_employe du module employé.
• La fonction void recherche(liste l1, char nom[],liste &l2) recherche dans la liste l1 tous les employés portant
le nom nom et met ces employés dans la liste l2. l1et nom sont des paramètres en entrée de la fonction
affiche et l2 sera un paramètre en sortie.
• le module menu
• Ce module contient l'interface homme machine de notre application.
Programmation C++ (débutant)/Les structures 14

• La fonction void menu(liste &l) permet de gérer la liste l grâce à notre menu. Cette fonction contient la
boucle do … while principale de notre programme.
• La fonction int choix() affiche le menu de notre programme, demande à l'utilisateur de faire un choix dans
le menu et renvoie ce choix par un return.
• La fonction bool traiter_choix(liste &l,int choix) effectue le traitement désigné par l'entier choix sur la liste
l. Si ce choix a pour conséquence la sortie du menu principal la fonction renvoie true, sinon elle renvoie
false. Cette fonction est essentiellement constituée d'un switch et de l'appel à des fonction du module liste.

Structuration de notre programme


Il y a de nombreuses fonctions courtes (moins de 20 lignes) réalisant chacune une fonction bien précise.
Ces fonctions sont rassemblées en 3 modules : employe, liste et menu plus bien sûr le programme principal.
Cette structuration (qui peut apparaître au départ fastidieuse) permet de développer plus rapidement en rendant plus
courte la phase de débogage.
Il est très facile de rajouter de nouvelles fonctionnalités dans notre application.

Approche modulaire et compilation séparée


Notre programme est constitué de 3 modules et de 7 fichiers.
Lorsqu'un seul des modules est modifié le compilateur ne va pas recompiler la totalité des fichiers de notre
applications mais seulement ceux qui ont été modifiés.
Ce point peut être important lorsqu'un programme est constitué de centaines de modules.

Conclusion
La notion de structure est une notion très importante en programmation et nous permet de définir des éléments plus
complexes que les simples types de base.
Elles permettent de gagner un niveau d'abstraction supplémentaire par rapport aux type de base.
L'approche modulaire permet d'affiner notre méthodologie de programmation et de structurer notre réflexion en
plusieurs phases :
- comment représenter une notion donnée ?
- quelles sont les fonctions nécessaires pour manipuler cette notion ?
- La phase technique : comment écrire ces fonctions ?
On constate que la phase technique, bien qu'indispensable, n'est pas l'élément crucial du développement d'un
programme : en amont, il y a une phase d'analyse et de structuration bien plus importante.

Exercices sur les structures

EXERCICE 1
a) Écrire une structure fraction composée de 2 entiers : un numérateur et un dénominateur.
b) Écrire une fonction pgcd de 2 entiers positifs.
c) Écrire une fonction normalise qui normalise une fraction de la manière suivante :
- le numérateur et le dénominateur doivent être premier entre eux
- le dénominateur est positif
d) Écrire une fonction saisir qui permet de saisir une fraction.
e) Écrire une fonction affiche qui affiche une fraction.
f) Écrire une fonction somme qui calcule la somme de 2 fractions. Le résultat doit être normalisé.
g) Écrire 3 autres fonctions : différence, multiplie et divise comme au f)
h) Écrire un programme qui permet de saisir les fractions A, B, D, E et F et qui calcule (A+B)/(D-E*F) .
Programmation C++ (débutant)/Les structures 15

Le résultat sera affiché à l’écran.

EXERCICE 2
On veut gérer des produits dans un entrepôt. Un produit est défini par 2 chaînes de caractères : le code produit
("H567" par exemple et qui comporte au maximum 9 caractères utiles), l'intitulé ("pots de peinture" et qui comporte
au maximum 99 caractères utiles) et un entier qui indique la quantité en stock (803 par exemple). Il faut gérer une
liste de produits en veillant à ce qu'il n'y ait pas deux produits avec le même code produit. Bien sûr la quantité en
stock ne peut pas être négative. La liste comportera au maximum 100 produits.
Il faut gérer la liste grâce au menu suivant :
1. Ajouter un produit (on tape le code produit et l'intitulé, la quantité est initialisée à 0).
2. Afficher la liste de produits.
3. Supprimer un produit en tapant le code produit.
4. Acheter un produit en tapant le code produit et la quantité achetée.
5. Vendre un produit en tapant le code produit et la quantité vendue.
6. Quitter
On veillera à bien décomposer ce problème en différents modules et à mener une réflexion sur les fonctions
nécessaires dans chaque module.

EXERCICE 3
On veut écrire un programme qui permet de gérer une liste de disques. Un disque est défini par un code référence
(une chaîne de caractères par exemple "H345"), nom de chanteur, un nom de chanson et prix. Le code référence fera
au maximum 9 caractères utiles, le titre du disque et le nom du chanteur feront au maximum 99 caractères utiles.
On veut gérer une liste de disques grâce au menu suivant :
1. Ajouter un disque à la liste.
2. Afficher la liste.
3. Supprimer un disque grâce à son code référence.
4. Afficher tous les disques d'un chanteur donné.
5. Afficher tous les disques ayant un titre donné.
6. Quitter
On veillera à bien décomposer ce problème en différents modules et à mener une réflexion sur les fonctions
nécessaires dans chaque module.
Sources et contributeurs de l’article 16

Sources et contributeurs de l’article


Programmation C++ (débutant)/Les structures Source: [Link] Contributeurs: Charly, DavidL, JackPotte, Merrheim, [Link], Sub, Zulul,
32 modifications anonymes

Licence
Creative Commons Attribution-Share Alike 3.0 Unported
http:/ / creativecommons. org/ licenses/ by-sa/ 3. 0/
Programmation C++ (débutant)/Les pointeurs 1

Programmation C++ (débutant)/Les pointeurs


Le cours du chapitre 10 : Les pointeurs

Présentation
Les pointeurs sont une des difficultés majeures du C++. Nous apprendrons dans ce chapitre à les manipuler. Ce sera
l'occasion d'étudier les fonctions avec passage de paramètres par pointeur . Ce passage de paramètres peut sembler
obsolète et on peut penser qu'il vaut mieux utiliser le passage de paramètres par référence mais tout programmeur en
C++ se doit de le connaître et il est toujours très utilisé.
Nous étudierons également les liens entre les tableaux et les pointeurs. Jusqu'à maintenant, nous manipulions des
tableaux dont la taille était constante. Nous étudierons dans ce chapitre les tableaux dynamiques dont la taille peut
être quelconque et variable au cours du temps.
Ce sera l'occasion d'étudier l'allocation dynamique de mémoire qui permet au programmeur de gérer la RAM comme
bon lui semble en créant ou en détruisant de nouvelles structures. A l'occasion d'exercices, nous verrons une
structure de données plus complexe : des listes constitués de tableaux dynamiques dont la taille peut s'allonger au fur
et à mesure des besoins.

Une notion délicate


Il s'agit d'une notion importante du C++ mais qui est assez délicate à utiliser. Les pointeurs semblent au départ assez
pratique à utiliser mais de nombreux bogues résultent de leur utilisation. Il convient donc de savoir les utiliser mais
la prudence doit être de rigueur !

Déclaration
• Déclaration d'un pointeur : int * x;
• x est un pointeur vers un entier : x contient l'adresse en mémoire où est stocké un entier. Initialement le pointeur
n'est pas initialisé : x vaut donc n'importe quelle adresse en RAM.

L'opérateur &
Si a est un entier, &a renvoie l'adresse réelle en mémoire de la variable a.
On peut donc écrire :

int a;
int *x;
x=&a;

Dans ce bout de programme, on a copié l'adresse où est stockée en mémoire la variable a dans le pointeur x.
Attention ! On a copié une adresse vers un entier, pas un entier.
On dit que x pointe vers la variable a.
Programmation C++ (débutant)/Les pointeurs 2

L'opérateur de déréférencement *
Si x est un pointeur vers un entier, *x sera l'entier pointé par x.
Ainsi si on écrit :

int a=25;
int *x;
x=&a;
*x=25;

Comme x est un pointeur vers a, *x désigne la variable a.


L'instruction *x=25; copie un entier dans un autre et non une adresse. On copie donc l'entier 25 dans la variable
a.

Exemple 1 : utilisation de pointeurs


#include<iostream>
using namespace std;

int main()
{
int a;
int *x,*y;

a=90;
x=&a;
cout << *x << endl;

*x=100;
cout << "a vaut : " << a << endl;

y=x;
*y=80;
cout << "a vaut : " << a << endl;

return 0;
}

Explications
• Dans cet exemple, on définit un entier a et deux pointeurs vers des entiers x et y.
a est initialisée à la valeur 90.
• Après l'instruction x=&a, x pointe vers a. x contient l'adresse en mémoire où est stockée la variable a.
• L'instruction *x=100; modifie le contenu de la variable a et met la valeur 100 dans cette variable.
• L'instruction y=x copie le pointeur x dans le pointeur y. Après cette instruction, les deux pointeurs x et y pointent
vers la même variable a.
• Lorsqu'on écrit *y=80, on modifie alors le contenu de la variable a qui vaut alors 80.
• On voit donc sur cet exemple qu'un pointeur permet de modifier indirectement le contenu d'une variable.
Programmation C++ (débutant)/Les pointeurs 3

Exécution
Lorsqu'on exécute le programme voici ce qu'on obtient à l'écran :

90
a vaut : 100
a vaut : 80

Exemple 2 : un autre exemple d'utilisation de pointeurs


#include<iostream>
using namespace std;

int main()
{
int a,b;
int *x,*y;

a=50;
b=80;
x=&a;
y=&b;
*x=*y;
cout << "a vaut : " << a << endl;

x=y;
*x=1000;
cout << "b vaut : " << b << endl;
return 0;
}

Explications
• Dans cet exemple, on déclare deux entiers a et b et deux pointeurs vers des entiers x et y.
• a est initialisé à 50 et b à 80.
• L'instruction x=&a fait pointer x vers a.
• L'instruction y=&b fait pointer y vers b.
• L'instruction *x=*y copie l'entier pointé par y dans l'entier pointé par x c'est-à-dire copie b dans a. On a copié des
entiers. a vaut donc 80.
• On affiche ensuite la valeur de a c'est-à-dire 80.
• L'instruction x=y copie le pointeur y dans le pointeur x : x pointe maintenant vers l'entier b (tout comme y
d'ailleurs). On a copié des pointeurs.
• L'instruction *x=1000 met la valeur 1000 dans l'entier pointé par x c'est-à-dire dans b. b vaut alors 1000.
• On affiche ensuite la valeur de b c'est-à-dire 1000.
• Dans cet exemple, il faut bien comprendre que parfois on copie des entiers, parfois on copie des pointeurs.
Programmation C++ (débutant)/Les pointeurs 4

Exécution
Lorsqu'on exécute le programme voici ce qu'on obtient à l'écran :

a vaut : 80
b vaut : 1000

Passage de paramètres par pointeurs


• Lorsqu'on passe un pointeur en paramètre, on peut avoir un effet semblable au passage de paramètres par
références.
• On préfère toutefois assez souvent le passage de paramètres par référence.
• Il faut connaître les 2 méthodes.

Exemple 3 : passage de paramètres par pointeur


#include<iostream>
using namespace std;

void minmax(int i, int j, int* min, int* max)


{
if(i<j) { *min=i; *max=j; }
else { *min=j; *max=i; }
}

int main()
{
int a, b, w, x;
cout << "Tapez la valeur de a : "; cin >> a;
cout << "Tapez la valeur de b : "; cin >> b;

minmax(a, b, &w, &x);


cout << "Le plus petit vaut : " << w << endl;
cout << "Le plus grand vaut : " << x << endl;
return 0;
}

Explications
• Dans cet exemple, on a une fonction minmax qui a comme paramètres 2 entiers i et j et 2 pointeurs vers des
entiers min et max. Cette fonction trouve le plus petit de i et de j et le met dans l'entier pointé par min. Elle trouve
le plus grand des 2 entiers et le copie dans l'entier pointé par max.
• Dans la fonction main(), on déclare 4 entiers a, b, w, et x. On demande à l'utilisateur de saisir au clavier les entiers
a et b. Lors de l'appel de fonction minmax(a,b,&w,&x), on copie la valeur de a dans i, la valeur de b dans j. On
copie la valeur de &w (un pointeur vers w) dans min et on copie &x (un pointeur vers x) dans max: min pointe
donc vers w et max vers x. Lors de l'appel, on va donc récupérer dans w le plus petit des entiers a et b et dans x le
plus grand de ces 2 entiers.
Programmation C++ (débutant)/Les pointeurs 5

Exécution
Lorsqu'on exécute le programme voici ce qu'on obtient à l'écran :

Tapez la valeur de a : 25
Tapez la valeur de b : 12
Le plus petit vaut : 12
Le plus grand vaut : 25

Exemple 4 : passage de paramètres par référence


#include<iostream>
using namespace std;

void minmax(int i, int j, int& min, int& max)


{
if(i<j) { min=i; max=j; }
else { min=j; max=i; };
}

int main()
{
int a, b, w, x;
cout << "Tapez la valeur de a : "; cin >> a;
cout << "Tapez la valeur de b : "; cin >> b;

minmax(a, b, w, x);
cout << "Le plus petit vaut : " << w << endl;
cout << "Le plus grand vaut : " << x << endl;
return 0;
}

Explications
• Au lieu d'utiliser un passage de paramètres par pointeur comme dans l'exemple 3, on peut bien sûr utiliser un
passage de paramètres par référence.
• Dans cet exemple, la fonction minmax possède 4 paramètres : 2 entiers i et j passés par valeur et 2 entiers min
et max passés par référence. i et j sont les paramètres en entrée de la fonction minmax. min et max sont les
paramètres en sortie de cette fonction.
• Lors de l'écriture de la fonction minmax, on remarquera le symbole & placé après le type qui indique que le
paramètre est passé par référence.
• Lors de l'appel de minmax, on remarquera qu'il s'écrit minmax(a,b,w,x); sans symbole particulier. a et b sont
passés par valeur et w et x sont passés par référence.
Programmation C++ (débutant)/Les pointeurs 6

Exécution
Lorsqu'on exécute le programme voici ce qu'on obtient à l'écran :

Tapez la valeur de a : 20
Tapez la valeur de b : 10
Le plus petit vaut : 10
Le plus grand vaut : 20

La taille des paramètres d'une fonction


Lorsqu'on passe par valeur un paramètre à une fonction, ce paramètre est recopié juste avant l'appel. Si ce paramètre
est une structure qui contient par exemple un tableau de taille importante, le temps nécessaire pour cette recopie peut
être déraisonnable.

Différentes solutions possibles


Si un paramètre l de type T passé en paramètre à une fonction a une taille très importante, pour gagner du temps lors
de l'appel on peut :
• passer ce paramètre par pointeur car la taille d'un pointeur est faible (en général 4 octets). Par contre cela donne la
possibilité de modifier ce paramètre dans le corps de la fonction. Le paramètre sera de type T*.
• passer ce paramètre par référence car la taille d'une référence est faible (en général 4 octets). Par contre cela
donne également la possibilité de modifier ce paramètre dans le corps de la fonction. Le paramètre sera de type T
&.
• ces 2 solutions sont problématiques car parfois il est intéressant d'empêcher le programmeur de modifier l dans le
corps de la fonction pour éviter les bugs.
• On peut également passer une référence vers une constante de type T : la taille du paramètre sera alors très petite
(4 octets en général) et on peut empêcher le programmeur de modifier ce paramètre dans le corps de la fonction.
• Le paramètre de la fonction sera alors de type const T &.
• Cette solution sera désormais privilégiée pour passer à une fonction un paramètre de taille important en entrée
uniquement.

Allocation dynamique de mémoire


• Un programme en C++ est capable de demander au système d'exploitation de la mémoire pour y stocker des
données et de libérer ces zones mémoire au cours de l'exécution du programme : on appelle cela l'allocation
dynamique de mémoire.
• Le programmeur est tenu de "rendre" au système d'exploitation, les zones mémoire qu'il aura réclamé
dynamiquement, au plus tard lors de la fermeture du programme.
• Il existe deux méthodes pour effectuer de l'allocation dynamique de mémoire :
• L'ancienne méthode qui utilise les fonctions malloc et free.
• Une méthode plus récente qui utilise les mots-clés new et delete.

malloc et free
Il s'agit de 2 appels système standards :
• La fonction (void *) malloc(int t) demande au système de fournir une zone mémoire de t octets et renvoie par un
return un pointeur vers cette zone (ou le pointeur NULL s'il n'y a pas assez de mémoire). cette fonction renvoie un
élément de type void *, c'est-à-dire un pointeur vers n'importe quelle type. En général, on effectue un cast pour
transformer ce pointeur vers un pointeur vers un autre type, un pointeur vers un int par exemple.
• La fonction void free(void *p) libère la zone mémoire pointée p.
Programmation C++ (débutant)/Les pointeurs 7

Tableaux de taille variable


Grâce à malloc et free, on peut gérer des tableaux dont la taille est variable : un tableau peut s'allonger ou se réduire
en fonction des besoins du programmeur. On appelle cela de l'allocation dynamique de mémoire. Ne pas oublier de
libérer la mémoire.
Pour demander au système d'exploitation une zone de la bonne taille, il peut être utile de connaître la taille occupée
par un int, un char, ou n'importe quelle type structuré par exemple. Pour cela,on peut utiliser le mot-clé sizeof(type)
qui a en paramètre un type quelconque et qui renvoie la taille en octets occupée par une variable de ce type.

Exemple 5 : tableaux de taille variables avec malloc et free


#include<iostream>
using namespace std;
#include<cstdlib>

int main()
{
int *t;
int i;

t = (int *) malloc( 5 * sizeof(int) );

if (t==NULL)
cout << "pas assez de mémoire" << endl;
else
{
for(i=0 ; i<5 ; i++)
t[i] = i * i;

for(i=0 ; i<5 ; i++)


cout << t[i] << " ";

cout << endl;


free(t);
}

t = (int *) malloc( 10 * sizeof(int) );

if (t==NULL)
cout << "pas assez de mémoire" << endl;
else
{
for(i=0;i<10;i++)
t[i] = i * i;

for(i=0 ; i<10 ; i++)


cout << t[i] << " ";

cout << endl;


Programmation C++ (débutant)/Les pointeurs 8

free(t);
}
return 0;
}

Explications
• Dans cet exemple, t est un pointeur vers un entier.
• Après l'appel à la fonction malloc dans l'instruction t=(int *)malloc(5*sizeof(int)), t contient
l'adresse d'une zone mémoire dont la taille est 5 fois la taille d'un entier. La variable t devient ainsi un tableau de
5 entiers qu'on peut utiliser comme n'importe quel tableau d'entiers.
• Si t n'est pas NULL, ce qui signifie qu'il y avait assez de mémoire disponible, alors on peut accéder à n'importe
quelle élément du tableau en écrivant t[i] (i étant bien sûr compris entre 0 et 4).
• Dans ce programme, on remplit les 5 cases du tableau t en mettant i*i dans la case i et on affiche ce tableau.
• Ensuite, on libère l'espace occupé par le tableau en appelant la fonction free(t). t devient alors un pointeur
non initialisé et on a plus le droit d'accéder aux différentes cases du tableau qui a été détruit.
• On appelle ensuite la fonction t=(int *)malloc(10*sizeof(int)); t devient alors cette fois-ci un
tableau à 10 cases (sauf si t est NULL) et on peut accéder à la case i en écrivant t[i] (i compris entre 0 et
9).
• Dans ce programme, on remplit les 10 cases du tableau t en mettant i*i dans la case i et on affiche ce
tableau.
• On détruit ensuite la tableau t en appelant free(t).

Exécution
Lorsqu'on exécute le programme voici ce qu'on obtient à l'écran :

0 1 4 9 16
0 1 4 9 16 25 36 49 64 81

new et delete
• new et delete sont 2 mots-clés permettant de faire de l'allocation dynamique de mémoire de manière plus
performante que malloc et free.
• on préférera utiliser new et delete que malloc et free.

Utilisation de new
Syntaxe :
new type[taille];
new renvoie un tableau dont la taille est taille éléments, chaque élément étant de type type. S'il n'y a pas assez de
mémoire, new renvoie NULL.
new renvoie un élément dont le type est type *.
Programmation C++ (débutant)/Les pointeurs 9

Utilisation de delete
Syntaxe :
delete []t;
Si t est un tableau qui a été créé en utilisant la méthode précédente, l'utilisation de delete détruit ce tableau. Le
tableau t n'est donc plus utilisable dès qu'on a utilisé l'opérateur delete.

Exemple 6 : tableaux de taille variable avec new et delete


#include<iostream>
using namespace std;

int main()
{
int *t;
int i;

t = new int[5];
if (t == NULL )
cout << "pas assez de mémoire" << endl;
else
{
for ( i=0 ; i<5 ; i++ )
t[i] = i * i;
for ( i=0 ; i<5 ; i++ )
cout << t[i] << " ";
cout << endl;

delete [] t;

t = new int[10];
if (t == NULL)
cout << "pas assez de mémoire" << endl;
else
{
for ( i=0 ; i<10 ; i++ )
t[i] = i * i;
for ( i=0 ; i<10 ; i++ )
cout << t[i] << " ";
cout << endl;
delete [] t;
}
}
return 0;
}
Programmation C++ (débutant)/Les pointeurs 10

Explications
• Dans cet exemple, t est un pointeur vers un entier.
• Grâce à l'opérateur new, on transforme t en un tableau de 5 entiers grâce à l'instruction. t=new int[5]; On remplit
ce tableau et on affiche le contenu des 5 cases de ce tableau. On détruit ce tableau en utilisant l'instruction delete [
]t;
• On crée ensuite un autre tableau comportant cette fois 10 cases, on le remplit, on l'affiche et on le détruit de la
même manière que précédemment.

Exécution
Lorsqu'on exécute le programme voici ce qu'on obtient à l'écran :

0 1 4 9 16
0 1 4 9 16 25 36 49 64 81

Tableaux statiques et pointeurs


Lorsqu'on écrit int t[10];, t est en fait un pointeur non modifiable (constant donc) vers une zone de 10 fois la taille
d'un entier (4 octets) donc vers une zone de 40 octets. t pointe vers t[0].

Incrémentation d'un pointeur


• Lorsqu'on incrémente un pointeur p en écrivant p++ p est incrémenté de la taille de l'élément pointé. Si p par
exemple pointe vers un élément i d'un tableau, après p++, il pointe vers l'élément i+1.
• Lorqu'on écrit p[i], on rajoute en fait à p la valeur i fois la taille du type pointé et on déréférence ce pointeur.
• Il est toutefois recommandé d'utiliser ces opérations sur les pointeurs avec une extrême prudence.

Exemple 7 : incrémentation de pointeurs


#include<iostream>
using namespace std;

int main()
{
int t[10];
int i;

for ( i=0 ; i<10 ; i++)


t[i] = i * i;

int* x;
x=t; // pointeur vers le premier élément
for ( i=0 ; i<10 ; i++)
{
cout << *x << " ";
x++; // pointeur vers l'élément suivant
}
cout << endl;

return 0;
}
Programmation C++ (débutant)/Les pointeurs 11

Explications
• Dans cet exemple, t est un tableau statique de 10 entiers et x est un pointeur vers un entier.
• L'instruction x=t; permet de faire pointer x vers la première case du tableau t. Il est équivalant d'écrire x=t; que
d'écrire x=&t[0];
• À l'intérieur d'une boucle for, on va afficher *x, c'est-à-dire l'entier pointé par t et à chaque étape, on écrit x++, ce
qui incrémente la valeur de t de la taille d'un entier.
• x va donc pointer successivement t[0], t[1],…etc…t[9]. On va donc afficher une à une toutes les cases du tableau.

Exécution
Lorsqu'on exécute le programme voici ce qu'on obtient à l'écran :

0 1 4 9 16 25 36 49 64 81

Exemple 8 : parcours d'un tableau de char par un pointeur


#include<iostream>
using namespace std;

int main()
{
char c[100];
cout << "Tapez une chaîne : ";
cin >> c;

char *p;
p=c; // pointeur vers le premier caractère
while(*p!='\0')
{
cout << *p << endl;
p++; // pointeur vers le caractère suivant
}
return 0;
}

Explications
• Dans cet exemple, c est un chaîne de caractères : on demande à l'utilisateur par un cin de saisir la valeur de cette
chaîne.
• p est un pointeur vers un char. Lorsqu'on écrit p=c, p pointe vers le premier caractère de la chaîne.
• Dans une boucle while, on va afficher le caractère pointé par p grâce à l'instruction cout<<*p<<endl; et on fait
pointer p vers le caractère suivant de la chaîne en écrivant p++;. On quittera le while lorsque *p vaudra '\0',
c'est-à-dire lorsque p pointera vers le caractère de fin de chaîne.
• On aura donc afficher un à un tous les caractères de la chaîne.
Programmation C++ (débutant)/Les pointeurs 12

Exécution
Lorsqu'on exécute le programme voici ce qu'on obtient à l'écran :

Tapez une chaîne : BONJOUR


B
O
N
J
O
U
R

Conclusion
Les pointeurs constituent une notion fondamentale du C++. Elle est utilisée pour passer des paramètres à une
fonction ou pour créer des structures de données complexes comme des tableaux de taille variable. Elle est toutefois
complexe à utiliser et source de nombreux bugs. Elle est d'ailleurs très controversée et on peut remarquer qu'elle a
disparu dans des langage de programmation plus récent que le C++ comme le langage Java. Tout programmeur en
C++ se doit toutefois de connaître cette notion encore très importante et très utilisée.

Exercices

Exercice 1
Ecrire une fonction swap qui a comme paramètres deux pointeurs vers des entiers et qui échange le contenu des deux
entiers pointés. Tester cette fonction en écrivant un programme qui échange le contenu de deux entiers a et b en
appelant cette fonction.

Exercice 2
Ecrire une fonction qui a comme paramètres un tableau d'entiers de taille quelconque, la taille du tableau, et 2
pointeurs vers des entiers min et max. La fonction doit renvoyer dans les entiers pointés par min et max
respectivement les plus petits et les plus grands entiers du tableau.

Exercice 3
Écrire une fonction qui a en paramètre une chaîne de caractères et qui renvoie par un return le nombre d'occurrences
de la lettre 'A'. Cette fonction devra parcourir la chaîne en utilisant un pointeur. Tester cette fonction.

Exercice 4
Ecrire une fonction qui a comme prototype copy(char * ch1, char * & ch2). Cette fonction a comme paramètre en
entrée une chaîne de caractères ch1 et une référence vers un pointeur ch2. Avant l'appel ch2 est un pointeur non
initialisé. Après l'appel, ch2 pointe vers un nouveau tableau de char qui contient une copie de la chaîne ch1. Ce
nouveau tableau de char aura la taille minimale nécessaire. Tester cette fonction.
Programmation C++ (débutant)/Les pointeurs 13

Exercice 5
Réécrire la fonction du 5 et le programme principal mais cette fois-ci le pointeur ch2 sera non plus passé par
référence mais par pointeur. La fonction copy aura donc comme prototype :

copy(char * ch1, char * * ch2)

Exercices 6
On veut écrire un programme qui permet de gérer une liste de notes grâce à un tableau de taille variable. Une note
sera définie par un nom (chaîne de 9 caractères utiles), un prénom (chaîne de 9 caractères utiles) et une valeur (un
réel). Notre structure listeNotes (qui contient une liste de notes) sera caractérisée par un pointeur vers une note qui
sera en fait un tableau de taille variable de notes, un entier nbmax qui sera la taille réelle du tableau, par un entier nb
qui sera le nombre d'éléments contenus dans la liste et un entier inc qui sera la taille initiale du tableau. Au départ, le
tableau fait inc cases et la liste et vide. On peut alors rajouter des éléments dans la liste. Lorsque le tableau devient
trop petit, on augmente la taille du tableau de inc cases. Pour cela , il faudra réallouer de la place pour un nouveau
tableau de notes plus grand que l'ancien. Il faudra ensuite copier les notes de l'ancien tableau dans le nouveau,
détruire l'ancien tableau et faire pointer le tableau de notes de notre vers notre nouveau tableau. Notre tableau verra
donc sa taille augmenter de inc cases à la fois au fur et à mesure des besoins. Lorsqu'on supprimera des notes dans le
tableau et dès qu'il y aura inc cases de vide dans le tableau on réduira de la même manière la taille du tableau. Notre
nouvelle structure listeNotes aura une gestion de la mémoire nettement meilleure qu'avec un tableau statique.
Notre liste de notes sera gérée par le menu suivant :

1. Ajouter une note.


2. Afficher une liste de notes.
3. Supprimer une note en tapant son nom et son prénom.
4. Afficher la moyenne des notes.
5. Quitter.

Il faudra veiller à ce qu'il n'y ait pas 2 notes avec le même nom et le même prénom dans la liste et il faudra trier la
liste de notes d'abord par rapport au nom, ensuite par rapport au prénom au fur et à mesure des ajouts et des
suppressions de notes. On veillera à bien décomposer ce problème en différents modules et à mener une réflexion sur
les fonctions nécessaires dans chaque module.
Programmation C++ (débutant)/Les classes 1

Programmation C++ (débutant)/Les classes


Le cours du chapitre 11 : Les classes

Une évolution des structures


Une fois introduite la notion de structures, on s'aperçoit qu'il est totalement naturel de créer des fonctions permettant
de manipuler ces structures. La notion de classe est donc une notion plus puissante que la notion de structures. Une
classe va permettre de regrouper en une seule entité des données membres et des fonctions membres appelées
méthodes.
Cependant, contrairement au langage C, les structures du C++ permettent cela également. La différence entre une
structure et une classe est que les attributs et méthodes d'une structure sont par défaut publics, alors qu'ils sont par
défaut privés dans une classe. Une autre différence est que les structures ne peuvent utiliser l'héritage.

Notion de classe
Une classe regroupera donc :
• des données membres.
• des méthodes membres qui seront des fonctions.

Un premier exemple de classe


• On veut manipuler des points définis par une abscisse et une ordonnée (des réels).
• Sur un point, on peut calculer la distance entre 2 points et le milieu de 2 points.
• Nous allons donc définir une classe Point définie par un fichier .h et un fichier .cpp.

Exemple 1 : la classe Point

Le fichier Point.h
#ifndef POINT_H
#define POINT_H

class Point
{
public:
double x,y;
double distance(const Point &P);
Point milieu(const Point &P);
};
#endif
Programmation C++ (débutant)/Les classes 2

Explications
On définit dans ce fichier la classe Point : elle contient 2 données de type double x et y et 2 méthodes membres
distance qui calcule la distance entre ce point et un autre Point et milieu qui calcule le milieu du segment composé de
ce point et d'un autre Point.
On remarque l'utilisation des directives de compilation #ifndef, #define et #endif pour gérer les inclusions multiple
du fichier header.

Le fichier [Link]
#include "Point.h"
#include <cmath>

double Point::distance(const Point &P)


{
double dx,dy;
dx = x - P.x;
dy = y - P.y;
return sqrt(dx*dx + dy*dy);
}

Point Point::milieu(const Point &P)


{
Point M;
M.x = (P.x+x) /2;
M.y = (P.y+y) /2;
return M;
}

Explications
• Il contient l'implémentation de chaque méthode de la classe Point.
• On fait précéder chaque méthode de Point::
• On a inclut le fichier cmath afin de pouvoir utiliser la fonction sqrt de cmath (racine carrée).
• A l'intérieur de la classe Point, on peut accéder directement à l'abscisse du point en utilisant la donnée membre x.
• On peut accéder à l'abscisse du paramètre P d'une méthode en utilisant P.x.

Le fichier [Link]
#include <iostream>
using namespace std;
#include "Point.h"

int main()
{
Point A, B, C;
double d;
cout << "SAISIE DU POINT A" << endl;
cout << "Tapez l'abscisse : "; cin >> A.x;
cout << "Tapez l'ordonnée : "; cin >> A.y;
cout << endl;
Programmation C++ (débutant)/Les classes 3

cout << "SAISIE DU POINT B" << endl;


cout << "Tapez l'abscisse : "; cin >> B.x;
cout << "Tapez l'ordonnée : "; cin >> B.y;
C = [Link](B);
d = [Link](B);
cout << endl;
cout << "MILIEU DE AB" << endl;
cout << "L'abscisse vaut : " << C.x << endl;
cout << "L'ordonnée vaut : " << C.y << endl;
cout << endl;
cout << "La distance AB vaut :" << d << endl;
return 0;
}

Explications
• Une fois inclus le fichier d'en-tête Point.h, on peut définir 3 points A, B et C.
• A, B et C sont 3 objets qui sont des instances de la classe Point.
• Les données membres étant publiques, on peut accéder à l'abscisse et à l'ordonnée de A en dehors de la classe en
écrivant A.x et A.y.
• Les méthodes membres distance et milieu étant publiques, on peut écrire directement [Link](B) ou
[Link](B).

Exécution
Lorsqu'on exécute ce programme, il s'affiche à l'écran :

SAISIE DU POINT A
Tapez l'abscisse : 3.2
Tapez l'ordonnée : 1.4
SAISIE DU POINT B
Tapez l'abscisse : 5
Tapez l'ordonnée : 6
MILIEU DE AB
L'abscisse vaut : 4.1
L'ordonnée vaut : 3.7
La distance AB vaut : 4.93964

Encapsulation
• Il faut éviter de donner un accès extérieur aux données membres d'un objet quelconque.
• On va interdire l'accès à certaines données membres d'une classe ou certaines méthodes en utilisant le mot clé
private.
• On ne peut accéder à une variable (ou une méthode membre) privée que par l'intérieur de la classe.
• par contre, on peut accéder librement à toutes les données membres ou méthodes membres publiques.
• Cette technique fondamentale permet d'empêcher au programmeur de faire n'importe quoi : il ne pourra accéder à
ces données que par les méthodes publiques.
Programmation C++ (débutant)/Les classes 4

Interface et boîte noire


• Vu de l'extérieur, on ne peut accéder à un objet donné que grâce à ces méthodes publiques.
• Ceci permet entre autre de protéger l'intégrité des données.
• L'ensemble des méthodes publiques est appelée l'interface de l'objet.
• De l'extérieur, l'objet peut être vu comme une boîte noire qui possède une interface d'accès.
• On cache ainsi à l'utilisateur de cette classe comment cette interface est implémentée : seul le comportement de
l'interface est important.

Accesseurs et mutateurs
• On pourra accéder aux valeurs des données membres privées grâce à des méthodes spécifiques appelée
accesseurs. Les accesseurs seront publics.
• On pourra même modifier ces valeurs grâce à des fonctions spécifiques appelées mutateurs.
• Cela permet au programmeur d'avoir un contrôle complet sur ces données et sur des contraintes en tout genre qu'il
veut imposer à ces données.

Exemple 2 : accesseurs et mutateurs

Le fichier Point.h
#ifndef POINT_H
#define POINT_H

class Point
{
public:
void setX(double x);
void setY(double y);
double getX();
double getY();
double distance(const Point &P);
Point milieu(const Point &P);
void saisir();
void afficher();

private:
double x,y;
};
#endif
Programmation C++ (débutant)/Les classes 5

Explications
• La méthode void setX(double x) est un mutateur qui permet de modifier la donnée membre privée x.
• Idem pour void setY(double y) avec la donnée membre privée y.
• Les méthodes double getX() et double getY() sont des accesseurs qui permettent d'accéder aux valeurs respectives
des données membres privées x et y.
• Les méthodes saisir() et afficher() permettent respectivement de saisir et d'afficher les coordonnées des points.

Le fichier [Link]
#include "Point.h"
#include <cmath>
#include <iostream>
using namespace std;

void Point::setX(double x)
{
this->x = x;
}
void Point::setY(double y)
{
this->y = y;
}

double Point::getX()
{
return x;
}

double Point::getY()
{
return y;
}

double Point::distance(const Point &P)


{
double dx, dy;
dx = x - P.x;
dy = y - P.y;
return sqrt(dx*dx + dy*dy);
}

Point Point::milieu(const Point &P)


{
Point M;
M.x = (P.x + x) /2;
M.y = (P.y + y) /2;
return M;
}
Programmation C++ (débutant)/Les classes 6

void Point::saisir()
{
cout << "Tapez l'abscisse : "; cin >> x;
cout << "Tapez l'ordonnée : "; cin >> y;
}

void Point::afficher()
{
cout << "L'abscisse vaut " << x << endl;
cout << "L'abscisse vaut " << y << endl;
}

Explications
• Dans la méthode setX(...), il y a une utilisation du mot-clé this. Le mot clé this désigne un pointeur vers l'instance
courante de la classe elle même. this->x désigne donc la donnée membre de la classe alors que x désigne le
paramètre de la méthode void setX(double x);
• Le mutateur double getX(); se contente de renvoyer la valeur de x.

Le fichier [Link]
#include <iostream>
using namespace std;
#include"Point.h"

int main()
{
Point A, B, C;
double d;
cout << "SAISIE DU POINT A" << endl;
[Link]();
cout << endl;
cout << "SAISIE DU POINT B" << endl;
[Link]();
cout << endl;
C = [Link](B);
d = [Link](B);
cout << "MILIEU DE AB" << endl;
[Link]();
cout << endl;
cout << "La distance AB vaut :" << d << endl;
return 0;
}
Programmation C++ (débutant)/Les classes 7

Explications
• On n'a plus le droit d'accéder aux données membres x et y sur les instances de Point A, B et C en utilisant A.x ou
B.y : il faut obligatoirement passer là une des méthodes publiques.
• Pour saisir la valeur de A, il suffit d'écrire [Link]();
• Pour afficher la valeur de A, il suffit d'écrire [Link]();

Exécution
Lorsqu'on exécute ce programme, il s'affiche à l'écran :

SAISIE DU POINT A
Tapez l'abscisse : 3.2
Tapez l'ordonnée : 1.4
SAISIE DU POINT B
Tapez l'abscisse : 5
Tapez l'ordonnée : 6
MILIEU DE AB
L'abscisse vaut : 4.1
L'ordonnée vaut : 3.7
La distance AB vaut : 4.93964

Utiliser les opérateurs >> et <<


• Pour pouvoir saisir un Point au clavier, on pourrait écrire tout simplement cin >> A; où A est une instance de la
classe Point.
• Pour écrire un Point à l'écran, on peut écrire tout simplement cout << B.
• Nous allons utiliser pour cela les fonctions operator>> et operator<<.
• Dans l'exemple 3, on utilisera une manière de procéder assez personnelle sans utiliser de fonctions amies;
• Dans l'exemple 4, nous verrons la méthode qui semble plus classique basée sur les fonctions amies.

Exemple 3 : l'opérateur >> et l'opérateur <<

Fichier Point.h
#ifndef POINT_H
#define POINT_H

#include <iostream>
using namespace std;

class Point
{
public:
void setX(double x);
void setY(double y);
double getX();
double getY();
double distance(const Point &P);
Point milieu(const Point &P);
void operator>>(ostream &out);
void operator<<(istream &in);
Programmation C++ (débutant)/Les classes 8

private:
double x, y;
};
#endif

Explications
• On définit une méthode operator>>(ostream &out); qui permet d'afficher le point en utilisant le
ostream out (le plus souvent ce sera cout).
• On définit une méthode operator<<(istream &in); qui permet de saisir le point au clavier en utilisant le
istream in (le plus souvent ce sera cin).

Le fichier [Link]
Les fonctions setX(), setY(), getX(), getY(), distance() et milieu sont identiques à celle de l'exemple 2. On définit les
2 opérateurs de la manière suivante :

void Point::operator>>(ostream &out)


{
out << "L'abscisse vaut " << x << endl;
out << "L'ordonnée vaut " << y << endl;
}

void Point::operator<<(istream &in)


{
cout << "Tapez l'abscisse : "; in >> x;
cout << "Tapez l'ordonnée : "; in >> y;
}

Fichier [Link]
#include <iostream>
using namespace std;
#include "Point.h"

int main()
{
Point A, B, C;
double d;
cout << "SAISIE DU POINT A" << endl;
A << cin;
cout << endl;
cout << "SAISIE DU POINT B" << endl;
B << cin;
cout << endl;
C = [Link](B);
d = [Link](B);
cout << "MILIEU DE AB" << endl;
C >> cout;
cout << endl;
cout << "La distance AB vaut :" << d << endl;
Programmation C++ (débutant)/Les classes 9

return 0;
}

Explications :
On peut directement saisir les coordonnées d'un point par A<<cin ou l'afficher à l'écran par A>>cout.

Exécution :
Lorsqu'on exécute ce programme, il s'affiche à l'écran :

SAISIE DU POINT A
Tapez l'abscisse : 3.2
Tapez l'ordonnée : 1.4
SAISIE DU POINT B
Tapez l'abscisse : 5
Tapez l'ordonnée : 6
MILIEU DE AB
L'abscisse vaut : 4.1
L'ordonnée vaut : 3.7
La distance AB vaut : 4.93964

La notation A<<cout
• On peut attacher l'opérateur de << à la classe Point comme dans l'exemple 3.
• Certains préfèrent toutefois écrire de manière plus usuelle : cout<<A;
• Ils argumentent parfois en disant qu'en plus cela permet d'enchaîner les affichages en écrivant :
cout<<A<<endl<<B;
• Il faudrait donc normalement définir une méthode operator<<(const Point &A) sur la classe
ostream.
• Or la classe iostream est déjà écrite !

Les fonctions amies


• Pour pouvoir écrire cout<<A; il faut écrire une fonction ostream & operator<<(ostream &,
const Point &P);
• Le plus pratique est que cette fonction ait le droit d'accéder aux données membres privées de la classe Point.
• On va donc la créer en tant que fonction amie en utilisant le mot-clé friend.
• L'abus de fonctions amies rompt avec le principe d'encapsulation : à utiliser avec précaution.

Exemple 4 : les fonctions amies

Le fichier Point.h
#ifndef POINT_H
#define POINT_H
class Point
{
friend istream & operator>>(istream &, Point &P);
friend ostream & operator<<(ostream &, const Point &P);
public:
void setX(double x);
Programmation C++ (débutant)/Les classes 10

void setY(double y);


double getX();
double getY();
double distance(const Point &P);
Point milieu(const Point &P);
private:
double x, y;
};
#endif

Explications
• Nous avons défini deux fonctions amies de la classe Point : ce ne sont pas des méthodes membres.
• Leurs définitions sont les suivantes :

friend istream & operator>>(istream &, Point &P);


friend ostream & operator<<(ostream &, const Point &P);

Elles renvoient respectivement une référence vers un istream et un ostream pour pouvoir enchaîner par exemple :
cout<<A<<B;

Le fichier [Link]
Voici l'implémentation de ces fonctions amies :

ostream & operator<<(ostream & out, const Point &P)


{
out << "L'abscisse vaut " << P.x << endl;
out << "L'ordonnée vaut " << P.y << endl;
return out;
}
istream & operator>>(istream & in,Point &P)
{
cout << "Tapez l'abscisse : "; in >> P.x;
cout << "Tapez l'ordonnée : "; in >> P.y;
return in;
}

Explications
• Nos 2 fonctions renvoient respectivement in et out par une instruction return afin de pouvoir enchaîner les
opérations de saisie et d'affichage.
• cout ne modifie pas notre Point : on passe donc une référence vers un Point constant.
• Pour cin, il faut passer en paramètre une référence vers un Point.

Le fichier [Link]
#include <iostream>
using namespace std;
#include "Point.h"

int main()
{
Programmation C++ (débutant)/Les classes 11

Point A, B, C;
double d;
cout << "SAISIE DU POINT A" << endl;
cin >> A;
cout << endl << "SAISIE DU POINT B" << endl;
cin >> B;
cout << endl;
C = [Link](B);
d = [Link](B);
cout << "MILIEU DE AB" << endl << C << endl;
cout << "La distance AB vaut :" << d << endl;
return 0;
}

Exécution
Lorsqu'on exécute ce programme, il s'affiche à l'écran :

SAISIE DU POINT A
Tapez l'abscisse : 3.2
Tapez l'ordonnée : 1.4
SAISIE DU POINT B

Tapez l'abscisse : 5
Tapez l'ordonnée : 6
MILIEU DE AB

L'abscisse vaut : 4.1


L'ordonnée vaut : 3.7
La distance AB vaut : 4.93964

Constructeurs et initialisation des données membres


• Par défaut, les données membres d'un objet ne sont pas initialisées. Il existe toutefois un constructeur par défaut
qui se contente de créer ces données membres. Il est appelé dès qu'une instance de la classe est crée. Les données
membres sont créées mais ne sont pas initialisées : elles sont à une valeur aléatoire correspondant à ce qu'il y
avait en mémoire à ce moment là.
• Il est vivement recommandé de définir un constructeur par défaut pour une classe donnée qui initialisera les
données membres : ainsi, il n'existera pas d'instance de la classe avec des données membres non initialisées.
• On peut également définir d'autres constructeurs qui permettront d'initialiser les données membres d'un objet avec
certaines valeurs.
• Le programmeur sera alors certain que ces données sont dans un état cohérent.
• Le constructeur peut éventuellement allouer dynamiquement de la mémoire pour une classe complexe : il faut
désallouer cette mémoire dès que l'objet n'existe plus.
Programmation C++ (débutant)/Les classes 12

Les destructeurs
• Le destructeur est appelé automatiquement dès qu'un objet est détruit. Il peut avoir (entre autres) pour rôle de
libérer par exemple la mémoire allouée au cours de l'utilisation de la classe.

Syntaxe des constructeurs et des destructeurs


• Le constructeur par défaut de la classe A sera noté A() . Il ne peut rien renvoyer par un return.
• On peut créer d'autres constructeur qui seront identifiés par leurs paramètres : par exemple un constructeur de la
classe A peut s'écrire A(int x, int y).
• Le destructeur de la classe A sera noté ~A(). Il ne renvoie rien par un return et ne peut pas avoir de paramètres.
• Il existe un destructeur par défaut qui se contente de détruire les données membres de l'objet.

Exemple 5 : constructeurs et destructeurs

Le fichier Point.h
#ifndef POINT_H
#define POINT_H
#include <iostream>
using namespace std;

class Point
{
public:
Point();
Point(double x, double y);
void setX(double x);
void setY(double y);
double getX();
double getY();
double distance(const Point &P);
Point milieu(const Point &P);
void operator>>(ostream &out);
void operator<<(istream &in);

private:
double x,y;
};
#endif
Programmation C++ (débutant)/Les classes 13

Explications
Par rapport à l'exemple précédent, nous avons rajouté 2 constructeurs :
• Le constructeur par défaut Point();
• Un autre constructeur Point(double x, double y);
• Le constructeur par défaut va initialiser l'abscisse et l'ordonnée de notre Point à 0.
• Le second constructeur va initialiser l'abscisse et l'ordonnée de notre Point respectivement à x et à y.

Ficher [Link]
Voici l'implémentation des 2 constructeurs :

Point::Point()
{
x = 0;
y = 0;
}

Point::Point(double x, double y)
{
this->x = x;
this->y = y;
}

Explications
• Le constructeur par défaut initialise x et y à la valeur 0.
• Pour le deuxième constructeur this->x désigne la données membre x de la classe et x désigne le paramètre du
constructeur.
• Idem pour this->y.

Fichier [Link]
#include <iostream>
using namespace std;
#include"Point.h"

int main()
{
Point A, B(3.4, 5.6);
cout << "Coordonnee du point A :" << endl;
A >> cout;
cout << endl << endl;
cout << "Coordonnee du point B :" << endl;
B >> cout;
cout << endl << endl;
return 0;
}
Programmation C++ (débutant)/Les classes 14

Explications
• Lorsqu'on déclare un objet par Point A; c'est le constructeur par défaut de la classe Point qui est appelé : l'abscisse
et l'ordonnée de A sont initialisées à 0.
• Lorsqu'on déclare un objet par Point B(3.4,5.6); c'est le deuxième constructeur qui est appelé l'abscisse de B est
initialisée à 3.4 et l'ordonnée à 5.6.

Exécution
Lorsqu'on exécute ce programme, il s'affiche à l'écran :

COORDONNEES DU POINT A
L'abscisse vaut : 0
L'ordonnée vaut : 0
COORDONNEES DU POINT B
L'abscisse vaut : 3.4
L'ordonnée vaut : 5.6

Liste d'initialisation
• Dans un constructeur, on peut intialiser des données dans la liste d'initialisation : il est d'ailleurs préférable de les
initialiser à cet endroit.
• Certaines données ne peuvent être initialisées qu'à cet endroit : les références par exemple.
• Lorsqu'on étudiera l'héritage, nous reparlerons de cette liste d'initialisation.

Exemple 6 : la liste d'initialisation


Nous allons réécrire les constructeurs des fichiers [Link] de l'exemple 5.

Fichier [Link]
Point::Point() : x(0),y(0)
{
}

Point::Point(double x, double y) : x(x),y(y)


{
}

Explications
• Lors de l'écriture d'un constructeur, on peut initialiser une donnée membre à 0 en écrivant x(0). C'est ce qui est
fait dans le constructeur par défaut Point() pour les données membres x et y.
• Pour le constructeur Point(int x, int y), on initialise la donnée membre x en écrivant x(x) : le premier x désigne la
donnée membre de la classe x, le deuxième x désigne le paramètre du constructeur.

Les opérateurs new et delete


• Si vous avez un pointeur p déclaré ainsi : A* p; Pour que p pointe vers une nouvelle instance de la classe A,
vous pouvez utiliser ainsi l'opérateur new : p= new A();
• Lorsque vous avez créé avec new une nouvelle instance d'un objet, vous êtes tenu de détruire cet objet avant la fin
de votre programme grâce à l'opérateur delete : delete p;
Programmation C++ (débutant)/Les classes 15

new et les constructeurs


• Si la classe A possède plusieurs constructeurs par exemple A(); et A(int,int); vous pouvez choisir le
constructeur de votre choix :

A *x, *y;
x = new A(); // constructeur A();
y = new A(4, 8); // constructeur A(int, int);

• Bien évidemment il ne faudra pas oublier de détruire les instances de la classe A créées en utilisant delete :

delete x;
delete y;

Exercices

EXERCICE 1
Écrire une classe Fraction dont le fichier d'en-tête est le suivant :

#ifndef FRACTION_H
#define FRACTION_H

#include<iostream>
using namespace std;

class Fraction
{
friend ostream & operator<<(ostream & out, const Fraction &f);
friend istream & operator>>(istream &in, Fraction &f);

public:
Fraction();
Fraction(int i);
Fraction(int num,int den);

Fraction operator+(const Fraction & f);


Fraction operator-(const Fraction & f);
Fraction operator*(const Fraction & f);
Fraction operator/(const Fraction & f);
private:
int num,den;
int pgcd(int x, int y);
void normalise();
};

#endif

Voici le rôle de chaque fonction :


• Fraction(); : le constructeur par défaut initialise la fraction à 0.
• Fraction(int); : initialise la fraction à l'entier i.
Programmation C++ (débutant)/Les classes 16

• Fraction(int num, int den); : initialise le numérateur et le dénominateur de la fraction.


• ostream & operator<<(ostream & out, const Fraction &f) : affiche à l'écran la fraction f.
• istream & operator>>(istream &in, Fraction &f) : saisit au clavier la fraction f.
• Fraction operator+(const Fraction & f); permet de faire la somme de 2 fractions.
• Fraction operator-(const Fraction & f); permet de faire la différence de 2 fractions.
• Fraction operator*(const Fraction & f); permet de faire la multiplications de 2 fractions.
• Fraction operator/(const Fraction & f); permet de faire la division de 2 fractions.
• int pgcd(int x, int y) : calcule le pgcd de 2 entiers.
• void normalise() : normalise la fraction. Le dénominateur doit être positif et la fraction irréductible.
Écrire un programme principal qui saisit au clavier 2 fractions f1 et f2 et qui affiche E=(f1+3/4-f2)/(f1*f2-5/8)+4.
Sources et contributeurs de l’article 17

Sources et contributeurs de l’article


Programmation C++ (débutant)/Les classes Source: [Link] Contributeurs: DavidL, Merrheim, Saamreivax, Sub, Tavernier, Trefleur, 37
modifications anonymes

Licence
Creative Commons Attribution-Share Alike 3.0 Unported
http:/ / creativecommons. org/ licenses/ by-sa/ 3. 0/
Programmation C++ (débutant)/La classe string 1

Programmation C++ (débutant)/La classe string


Le cours du chapitre 12 : La classe string

Présentation de la classe string


• Il s'agit d'une classe standard qui permet de représenter une chaîne de caractères.
• Pour l'utiliser, il faut rajouter #include <string>
• Cette classe encapsule des données pour pouvoir effectuer toutes les opérations de base sur les chaînes.
• Ces opérations sont assez complexes notamment la gestion de la mémoire : l'encapsulation permet de masquer à
l'utilisateur de la classe toutes les difficultés techniques.

Différentes opérations sur la classe string


• Déclaration et initialisation : string s1; string s2= "BONJOUR";
• Affichage et saisie : cout<<s2; cin>>s1;
• Concaténation : string s3=s2+s1;

Exemple 1 : la classe string


Fichier [Link]

#include <iostream>
#include <string>

using namespace std;

int main (void)


{
string s1, s2, s3;

cout << "Tapez une chaine : "; cin >> s1;


cout << "Tapez une chaine : "; cin >> s2;
s3 = s1 + s2;
cout << "Voici la concatenation des 2 chaines :" << endl;
cout << s3 << endl;
return 0;
}

Explications
• Dans cet exemple, nous étudions l'utilisation de la classe string.
• On peut saisir le contenu d'un chaîne en utilisant cin.
• On peut concaténer 2 chaînes grâce à l'opérateur +.
• On peut afficher une chaîne grâce à cout.
• Dans cet exemple, on demande à l'utilisateur de saisir 2 chaînes de caractères s1 et s2 et on affiche s3 la
concaténation de s1 et de s2.
Programmation C++ (débutant)/La classe string 2

Exécution
Lorsqu'on exécute ce programme, il s'affiche à l'écran :
Tapez une chaîne : AZERTY
Tapez une chaîne : QSDFGH
Voici la concaténation des deux chaînes :
AZERTYQSDFGH

Séparateurs
• Par défaut, lorsqu'on saisit une chaîne de caractères en utilisant cin, le séparateur est l'espace : cela empêche de
saisir une chaîne de caractères comportant une espace.
• La fonction getline(iostream &,string) permet de saisir une chaîne de caractères en utilisant le passage à la ligne
comme séparateur : notre chaîne de caractères peut alors comporter des espaces.

Exemple 2 : string avec des espaces


#include <iostream>
using namespace std;
#include<string>

int main (void)


{
string s1, s2, s3;

cout << "Tapez une chaine : "; getline (cin, s1);


cout << "Tapez une chaine : "; getline (cin, s2);
s3 = s1 + s2;
cout << "Voici la concatenation des 2 chaines :" << endl;
cout << s3 << endl;
return 0;
}

Explications
• Dans cet exemple, la chaîne de caractères s1 est saisie grâce à l'instruction getline(cin,s1) : cela permet de saisir
au clavier la chaîne s1, la fin de la chaîne est alors indiquée lorsqu'on tape sur ENTREE.
• On saisit ensuite la chaîne s2 et on affiche la concaténation des deux chaînes.

Exécution
Lorsqu'on exécute ce programme, il s'affiche à l'écran :
Tapez une chaîne : AZ ERTY
Tapez une chaîne : QS DFGH
Voici la concaténation des deux chaînes :
AZ ERTYQS DFGH
Programmation C++ (débutant)/La classe string 3

Analyse de chaînes
• Nombre de caractères d'une chaîne : size() est une méthode de la classe string qui renvoie le nombre de
caractères utiles.
• Récupération du i-ième caractère : la méthode const char at(int i) permet de récupérer le i-1ième caractère. (0 =
1er)

Exemple 3 : analyse de chaînes


#include <iostream>
#include<string>

using namespace std;

int main (void)


{
string s= "BONJOUR";
int i, taille = [Link] ();

cout << "La chaine comporte " << taille << " caracteres." << endl;

for (i = 0 ; i < taille ; i++)


cout << "caractère " << i << " = " << [Link](i) << endl;
return 0;
}

Explications
• La méthode size() sur un string permet de connaître la taille d'une chaîne de caractères.
• Si i est un entier [Link][i] permet de connaître le (i+1)-ième caractère de la chaîne ([Link][0] étant le premier caractère).
• Dans ce programme, on initialise la chaîne s à "BONJOUR" : on affiche ensuite la taille de la chaîne et on affiche
ensuite un à un chaque caractère.

Exécution
Lorsqu'on exécute ce programme, il s'affiche à l'écran :

La chaîne comporte 7 caractères


caractère 0 = B
caractère 1 = O
caractère 2 = N
caractère 3 = J
caractère 4 = O
caractère 5 = U
caractère 6 = R
Programmation C++ (débutant)/La classe string 4

Compatibilité avec les char * et les tableaux de char


• Transformation de chaîne de type C en string : on peut utiliser le constructeur string(char *) ou l'affectation
grâce au symbole = d'un char * vers une string.
• Transformation d'une string en chaîne de type C : il suffit d'utiliser la méthode : c_str() qui renvoie un char *
qui est une chaîne de type C.

Exemple 4 : compatibilité avec les tableaux de char et les char *


#include <iostream>
using namespace std;
#include<string>

int main (void)


{
string s1, s2;
char c1 []= "BONJOUR";
const char * c2;

s1 = c1;
cout << s1 << endl;
s2 = "AU REVOIR";
c2 = s2.c_str();
cout << c2 << endl;
return 0;
}

Explications
• Dans cet exemple, c1 est un tableau de 8 char contenant la chaîne "BONJOUR" (n'oubliez pas le caractère de fin
de chaîne '\0').
• Le pointeur c2 est un pointeur vers un tableau non modifiable de char.
• Les variables s1 et s2 sont des string.
• On peut affecter directement s1=c1 : le tableau de char sera transformé en string.
Dans c2, on peut récupérer une chaîne « de type C » identique à notre string en écrivant c2=s2.c_str().
• On peut transformer aisément une string en tableau de char et inversement.

Exécution
Lorsqu'on exécute ce programme, il s'affiche à l'écran :
BONJOUR
AU REVOIR

Transformation d'une chaîne en int ou double


• Pour transformer une chaîne en double ou en int, il faut transformer la chaîne en flot de sortie caractères : il s'agit
d'un istringstream.
• Ensuite, nous pourrons lire ce flot de caractères en utilisant les opérateurs usuels >>.
• La méthode eof() sur un istringstream permet de savoir si la fin de la chaîne a été atteinte.
• Chaque lecture sur ce flot grâce à l'opérateur >> renvoie un booléen qui nous indique d'éventuelles erreurs.
Programmation C++ (débutant)/La classe string 5

Exemple 5 : transformation de string en int


#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main (void)
{
string s;
cout << "Tapez une chaine : "; getline (cin, s);
istringstream istr(s);
int i;

if (istr >> i) cout << "VOUS AVEZ TAPE L'ENTIER " << i << endl;
else cout << "VALEUR INCORRECTE" << endl;
return 0;
}

Explications
• Dans cet exemple, s est une chaîne : on saisit une chaîne au clavier en utilisant getline(cin,s).
• On crée ensuite un istringstream appelé istr et construit à partir de s.
• On peut lire un entier i à partir de istr en utilisant : istr>>i .
• (istr>>i) renvoie true si un entier valide a pu être lu et renvoie false sinon.
• De la même manière, on pourrait lire des données d'autres types, double par exemple.

Exécution 1
Lorsqu'on exécute ce programme, il s'affiche à l'écran :
Tapez une chaîne : 12345
VOUS AVEZ TAPE L'ENTIER 12345

Exécution 2
Lorsqu'on exécute ce programme, il s'affiche à l'écran :
Tapez une chaîne : BJ9UYU
VALEUR INCORRECTE

EXERCICES

EXERCICE 1
On veut écrire une classe Note qui est représentée par 3 données membres : 2 chaînes de caractères nom et prénom et
un entier v qui est la valeur de la note. Grâce au constructeur par défaut la note est initialisée ainsi : le nom et le
prénom sont à la chaîne vide et la valeur note vaut 0.
Pour pouvoir accéder à la valeur du nom, prénom et de la note il y a un accesseur. Un unique mutateur permet de
modifier le nom, le prénom et la valeur de la note mais il doit respecter les contraintes suivantes :
Le nom et le prénom ne peuvent pas être la chaîne vide.
La note est comprise entre 0 et 20 bornes incluses
Le mutateur renvoie un booléen true si tout s'est bien passé false sinon.
On peut afficher la note grâce à l'opérateur << et en saisir une grâce à l'opérateur >>. On écrira une classe menu qui
gérer notre une note de la manière suivante :
Programmation C++ (débutant)/La classe string 6

1. Afficher la note
2. Modifier la note
0. Quitter
Écrire le programme principal qui crée notre note et qui appelle notre menu.
Programmation C++ (débutant)/Les fichiers 1

Programmation C++ (débutant)/Les fichiers


Généralité sur les fichiers
• La règle générale pour créer un fichier est la suivante :
• il faut l'ouvrir en écriture.
• on écrit des données dans le fichier.
• on ferme le fichier.
• Pour lire des données écrites dans un fichier :
• on l'ouvre en lecture.
• on lit les données en provenance du fichier.
• on ferme le fichier.

Fichiers textes ou binaires


Il existe 2 types de fichiers :
• les fichiers textes qui sont des fichiers lisibles par un simple éditeur de texte.
• les fichiers binaires dont les données correspondent en général à une copie bit à bit du contenu de la RAM. Ils ne
sont pas lisibles avec un éditeur de texte.

cstdio ou fstream
Il existe principalement 2 bibliothèques standard pour écrire des fichiers :
• cstdio qui provient en fait du langage C.
• fstream qui est typiquement C++.

Utilisation de cstdio

La fonction FILE * fopen(const char * filepath, char * mode)


Cette fonction permet d'ouvrir un fichier en lecture ou en écriture. Le paramètre filepath est un tableau de char
contenant le chemin du fichier sur lequel on souhaite travailler. Le paramètre mode indique le mode d'ouverture de
filepath : lecture ou écriture, texte ou binaire.
Le mode peut avoir l'une des valeurs suivantes :
• "r" (read) : lecture,
• "w" (write) : écriture, fichier créé ou écrasé s'il existait déjà,
• "a" (append) : écriture en fin de fichier existant (ajout de données).
Sur certaines plateformes (Windows par exemple), on peut y ajouter le type d'écriture (texte ou binaire), sur les
autres (Linux par exemple) le type est ignoré :
• "b" : mode binaire,
• "t" : mode texte.
Enfin, on peut ajouter le signe "+" afin d'ouvrir le fichier en lecture et écriture à la fois.
Exemples :
• "r+" : ouverture en lecture et écriture,
• "wb" : ouverture en écriture binaire.
Programmation C++ (débutant)/Les fichiers 2

La fonction fopen retourne le pointeur NULL si l'ouverture du fichier a échouée. Dans le cas contraire, elle retourne
un pointeur vers une structure FILE. Ce pointeur servira à écrire ou lire dans le fichier, ainsi qu'à le fermer.

La fonction fclose(FILE *)
Cette fonction permet de fermer un fichier, qu'il soit ouvert en lecture ou en écriture. On passe en paramètre à cette
fonction le pointeur FILE * fourni par la fonction fopen(...).

Les fichiers binaires


• La fonction fwrite(const void * buffer, int size,int nb, FILE * f) :
Cette fonction écrit nb élements de size octets (soit nb*size octets) à partir du pointeur buffer (dans la RAM) vers le
fichier f qui doit être ouvert en écriture. Il s'agit donc d'un transferts d'octets de la RAM dans un fichier.
• La fonction fread(const void * buffer, int size,int nb, FILE * f) :
Cette fonction lit nb élements de size octets (soit nb*size octets) à partir du fichier f (qui doit être ouvert en lecture)
vers le pointeur buffer (dans la RAM). Il s'agit donc d'un transferts d'octets d'un fichier vers la RAM.
• Exemple : écriture du fichier

#include <iostream>
#include<cstdio>
using namespace std;

int main (void)


{
FILE * f;
int a = 78, i, t1 [6];
double b = 9.87;
char c = 'W', t2 [10];

for(i = 0; i < 6; i++)


t1 [i] = 10000 + i;
strcpy (t2, "AZERTYUIO");
cout << t2 << endl;
f = fopen ("[Link]", "wb");
if (f == NULL)
cout << "Impossible d'ouvrir le fichier en écriture !" << endl;
else
{
fwrite (&a,sizeof(int),1,f);
fwrite (&b,sizeof(double),1,f);
fwrite (&c,sizeof(char),1,f);
fwrite (t1,sizeof(int),6,f);
fwrite (t2,sizeof(char),10,f);
fclose (f);
}

return 0;
}
Programmation C++ (débutant)/Les fichiers 3

Dans ce programme, on ouvre le fichier binaire nommé [Link] en écriture. Si on a réussi à ouvrir le fichier, on y
écrit un entier, un double, un char, puis un tableau de 6 entiers et finalement un tableau de 10 char.
On remarquera que pour écrire un entier il faut écrire &a pour obtenir un pointeur vers cet entier. Pour copier le
tableau t1 on écrire juste t1 car t1 est déjà un pointeur vers le premier élément du tableau.
• Exemple : lecture du fichier

#include <iostream>
#include<cstdio>
using namespace std;

int main (void)


{
FILE * f;
int a, t1 [6], i;
double b;
char c, t2[10];

f = fopen("[Link]", "rb");
if (f == NULL)
cout << "Impossible d'ouvrir le fichier en lecture !" << endl;
else
{
fread (&a,sizeof(int),1,f);
fread (&b,sizeof(double),1,f);
fread (&c,sizeof(char),1,f);
fread (t1,sizeof(int),6,f);
fread (t2,sizeof(char),10,f);
fclose (f);
}

cout << "a=" << a << endl


<< "b=" << b << endl
<< "c=" << c << endl;
for (i = 0; i < 6; i++)
cout << t1 [i] << endl;
cout << t2 << endl;

return 0;
}

Dans ce programme, on ouvre le fichier binaire nommé [Link] en écriture. Si on a réussi à ouvrir le fichier, on lit
un entier, un double un char, puis un tableau de 6 entiers et finalement un tableau de 10 char.
Programmation C++ (débutant)/Les fichiers 4

Les fichiers textes


• la fonction fprintf(FILE *f, const char * format,...)
La fonction fprintf permet d'écrire en mode texte dans un fichier différentes données. On n'oubliera pas de laisser un
espace entre les données pour pouvoir les relire (ou un passage à la ligne).
Le paramètre format permet de spécifier la nature des données et des caractéristiques sur leur écriture dans le fichier
(le nombre de caractères pare exemple.
Exemples de formats :
"%d" ==> indique un entier
"%lf" ==> indique un double
"%3.7lf" ==> indique un double avec 3 chiffres avant la virgule et 7 après.
"%s" ==> indique une chaine de caractères sans expace.
• la fonction fscanf(FILE * f, const char * format,...)
La fonction scanf permet de lire les données à partir d'un fichier texte en utilisant le format de données indiqué ( qui
est identique à printf).
• Exemple : écriture du fichier

#include <iostream>
#include<cstdio>
using namespace std;

int main (void)


{
FILE * f;
int a = 78, t1 [6], i;
double b = 9.87;
char c = 'W', t2 [10];

for (i = 0; i < 6; i++)


t1 [i] = 10000+i;
strcpy (t2, "AZERTYUIO");
f = fopen ("[Link]", "wt");
if (f == NULL)
cout << "Impossible d'ouvrir le fichier en écriture !" << endl;
else
{
fprintf (f, "%d %lf %c ", a, b, c);
for (i=0;i<6;i++)
fprintf (f, "%d ", t1[i]);
fprintf (f, "%s ", t2);
fclose (f);
}

return 0;
}

Dans ce programme, on ouvre le fichier texte nommé [Link] en écriture. Si on a réussi à ouvrir le fichier, on y écrit
un entier, un double, un char, puis un tableau de 6 entiers et finalement une chaîne de caractères sans espace contenu
Programmation C++ (débutant)/Les fichiers 5

dans un tableau de char.


• Exemple : lecture du fichier

#include <cstdlib>
#include <iostream>
#include<cstdio>
using namespace std;

int main (void)


{
FILE * f;
double b;
int a, t1 [6], i;
char c, t2 [10];

f = fopen ("[Link]", "rt");


if (f == NULL)
cout << "Impossible d'ouvrir le fichier en lecture !" << endl;
else
{
fscanf (f, "%d %lf %c ", &a, &b, &c);
for (i = 0; i < 6; i++)
fscanf (f, "%d ", &t1 [i]);
fscanf (f, "%s ", t2);
fclose (f);
}
cout << "a=" << a << endl
<< "b=" << b << endl
<< "c=" << c << endl;
for (i = 0; i < 6; i++)
cout << t1 [i] << endl;
cout << t2 << endl;

return 0;
}

Dans ce programme, on ouvre le fichier binaire nommé [Link] en lecture. Si on a réussi à ouvrir le fichier, on lit un
entier, un double, un char, puis un tableau de 6 entiers et finalement une chaîne de caractères.

Utilisation de fstream

Les fichiers textes


• La classe ofstream :
Il s'agit d'un fichier ouvert en écriture : pour créer un tel fichier il suffit d'appeler le constructeur qui a en paramètre
le nom du fichier : par exemple ofstream f("[Link]");.
Pour savoir si le fichier a bien été ouvert en écriture la méthode is_open() renvoie true si le fichier est effectivement
ouvert.
Programmation C++ (débutant)/Les fichiers 6

Pour écrire dans le fichier on utilise l'opérateur << sans oublier d'écrire des séparateurs dans le fichier texte.
• La classe ifstream :
Il s'agit d'un fichier ouvert en lecture : pour créer un tel fichier il suffit d'appeler le constructeur qui a en paramètre le
nom du fichier : par exemple ifstream f("[Link]");.
Pour savoir si le fichier a bien été ouvert en lecture la méthode is_open() renvoie true si le fichier est effectivement
ouvert.
Pour lire dans le fichier on utilise l'opérateur >>.
• Exemple : ecriture d'un fichier texte

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main(void)
{
int a = 78, t1 [6], i;
double b = 9.87;
char c = 'W';
string s;

for (i = 0; i < 6; i++)


t1 [i] = 10000+i;
s = "AZERTYUIO";
ofstream f ("[Link]");

if (!f.is_open())
cout << "Impossible d'ouvrir le fichier en écriture !" << endl;
else
{
f << a << " " << b << " " << c << endl;
for (i = 0; i < 6; i++)
f << t1 [i] << " ";
f << s;
}
[Link]();
return 0;
}

• Exemple : lecture d'un fichier texte

#include <iostream>
#include <fstream>
#include <string>

using namespace std;


Programmation C++ (débutant)/Les fichiers 7

int main (void)


{
int a, t1 [6], i;
double b;
char c;
string s;
ifstream f ("[Link]");

if (!f.is_open())
cout << "Impossible d'ouvrir le fichier en lecture !" << endl;
else
{
f >> a >> b >> c;
for (i = 0; i < 6; i++)
f >> t1 [i];
f >> s;
}
[Link]();
cout << "a=" << a << endl
<< "b=" << b <<endl
<< "c=" << c <<endl;
for (i = 0; i < 6; i++)
cout << t1 [i] << endl;
cout << s << endl;

return 0;
}

Les fichiers binaires


• La classe ofstream :
Pour ouvrir en écriture un fichier binaire, il suffit d'appeler le constructeur qui a en paramètre le nom du fichier et le
mode d'ouverture et fixer ce deuxième paramètre à ios::out | ios::binary: par exemple ofstream f("[Link]",ios::out
| ios::binary);.
Pour savoir si le fichier a bien été ouvert en écriture la méthode is_open() renvoie true si le fichier est effectivement
ouvert.
Pour écrire dans le fichier on utilise la méthode write((char *)buffer , int nb) pour écrire nb octets dans ce fichier.
• La classe ifstream :
Pour ouvrir en lecture un fichier binaire, il suffit d'appeler le constructeur qui a en paramètre le nom du fichier et le
mode d'ouverture et fixer ce deuxième paramètre à ios::in | ios::binary: par exemple ifstream f("[Link]",ios::in |
ios::binary);.
Pour savoir si le fichier a bien été ouvert en écriture la méthode is_open() renvoie true si le fichier est effectivement
ouvert.
Pour lire dans le fichier on utilise la méthode read((char *)buffer , int nb) pour lire nb octets de ce fichier.
• Ecriture d'un fichier binaire
Programmation C++ (débutant)/Les fichiers 8

#include <iostream>
#include <fstream>

using namespace std;

int main (void)


{
int a = 78, t1 [6], i;
double b = 9.87;
char c = 'W';

for (i = 0; i < 6; i++)


t1 [i] = 10000+i;

ofstream f ("[Link]", ios::out | ios::binary);

if(!f.is_open())
cout << "Impossible d'ouvrir le fichier en écriture !" << endl;
else
{
[Link] ((char *)&a, sizeof(int));
[Link] ((char *)&b, sizeof(double));
[Link] ((char *)&c, sizeof(char));
for (i = 0; i < 6; i++)
[Link] ((char *)&t1[i], sizeof(int));
}
[Link]();

return 0;
}

• lecture d'un fichier binaire

#include <iostream>
#include<fstream>
using namespace std;

int main (void)


{
int a, t1 [6], i;
double b;
char c;
string s;
ifstream f ("[Link]", ios::in | ios::binary);

if (!f.is_open())
cout << "Impossible d'ouvrir le fichier en lecture !" << endl;
else
Programmation C++ (débutant)/Les fichiers 9

{
[Link] ((char *)&a, sizeof(int));
[Link] ((char *)&b, sizeof(double));
[Link] ((char *)&c, sizeof(char));
for (i = 0; i < 6; i++)
[Link] ((char *)&t1[i], sizeof(int));
}
[Link]();

cout << "a=" << a << endl


<< "b=" << b << endl
<< "c=" << c << endl;
for (i = 0; i < 6; i++)
cout << t1 [i] << endl;

return 0;
}

Vous aimerez peut-être aussi