Cours C++
Cours C++
1
CHAPITRE 1:
1. HISTORIQUE DU C++ :
Le langage C++ est un des langages les plus célèbres au monde. Très utilisé, notamment
dans le secteur des jeux vidéo qui apprécie ses performances et ses possibilités, le C++ est
désormais incontournable pour les développeurs.
Les concepts de la programmation C++ ont été conçus par Bjarne Stroustrup en 1982 aux
ATT Bell Laboratoires. L’idée était d’ajouter au C des possibilités sur l’orienté objet et de
pallier aux inconvénients du C. De ce fait, le C++et en même temps un langage classique
comme le C et un langage orienté objet (P.O.O) comme JAVA.
En effet, Bjarne Stroustrup, son créateur, a cherché à adjoindre à un langage structuré
existant (le C), un certain nombre de spécificités lui permettant d’appliquer les concepts de
P.O.O. Dans une certaine mesure, il a permis à des programmeurs C d’effectuer une
transition en douceur de la programmation structurée vers la P.O.O. De sa conception jusqu’à
sa normalisation, le langage C++ a quelque peu évolué.
Le C++ est le descendant du langage C. Ces deux langages, bien que semblables au
premier abord, sont néanmoins différents. Le C++ propose de nouvelles fonctionnalités,
comme la programmation orientée objet (POO). Elles en font un langage très puissant qui
permet de programmer avec une approche différente du langage C.
2
2-DE L’ALGORITHME AU C++
Les choses ont ensuite évolué, heureusement. Le clavier et les premiers langages de
programmation sont apparus :
1958 : il y a longtemps, à l'époque où les ordinateurs pesaient des tonnes et faisaient la
taille de votre maison, on a commencé à inventer un langage de programmation appelé
l'Algol.
1960-1970 : ensuite, les choses ont évolué par la création d’un nouveau langage appelé le
CPL, qui évolua lui-même en BCPL, puis pris le nom de langage B.
1970 : puis, un beau jour, on en est arrivé à créer encore un autre langage qu'on a appelé... le
langage C, crée en 1972 par Dennis Ritchie ingénieur américain aux laboratoires Bell.
Ce langage, s'il a subi quelques modifications, reste encore un des langages les plus utilisés
aujourd'hui.
1983 : un peu plus tard, on a proposé d'ajouter des choses au langage C, de le faire évoluer.
Ce nouveau langage, que l'on a appelé "C++", est entièrement basé sur le C. Le langage C++
n'est en fait rien d'autre que le langage C avec plusieurs nouveautés. Il s'agit de concepts de
programmation poussés comme la programmation orientée objet.
Les programmes sont à la base de l'informatique. Ils demandent à votre ordinateur
d'exécuter des actions.
Pour écrire des programmes, on utilise un langage de programmation. Il en existe des
centaines.
Le C++ est un des langages de programmation les plus utilisés dans le monde.
Le C++ est un descendant du C. Il le complète en rajoutant un certain nombre de
possibilités.
3
Le C++ est un langage de bas niveau : il est plus proche du langage machine (le
binaire) et peut parfois être assez complexe.
Le C++ est un langage extrêmement rapide, ce qui en fait le langage de prédilection de
la plupart des jeux vidéo avides de performances.
Un débugger pour vous aider à traquer les erreurs dans votre programme (on n'a
malheureusement pas encore inventé le "correcteur", un truc qui corrigerait tout seul nos
erreurs.
4
Les instructions sont obligatoirement encapsulées dans des fonctions et il existe une
fonction privilégiée appelée main qui est le point de départ de tout programme.
Le canevas minimal à utiliser un programme C++ se présente ainsi :
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.
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.
5
Exemple : Code : C++ - Premier exemple de cin et cout
#include <iostream>
using namespace std;
int main()
{
cout << "Quel âge avez-vous ?" << endl;
int ageUtilisateur(0); //On prépare une case mémoire pour
stocker un entier.
cin >> ageUtilisateur; //On fait entrer un nombre dans cette case.
cout << "Vous avez " << ageUtilisateur << " ans !" << endl;
//Et on l'affiche.
return 0;
}
Je vous invite à tester ce programme. Voici ce que ça donne :
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 C++ , si, lors de la compilation, vous spécifiez un fichier d'en-tête
6
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 :
include <iostream>
Ce fichier est fourni par l’éditeur du compilateur : il s’agit d’un fichier C++ standard.
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.
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";
7
On peut écrire en une seule instruction :
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
8
CHAPITRE 2 :
SYNTAXE ELEMENTAIRE EN
LANGAGE C++
1- INTRODUTION
Avant d’approfondir la programmation C++ nous allons illustrer le principe de la syntaxe
élémentaire d’écriture d’un programme C++.
9
*/indique la fin du commentaire ou le commentaire compris entre ces deux symboles peut
tenir sur plusieurs lignes.
// Commentaires d’une seule ligne.
2-2-LES VARIABLES
Une variable a un nom et un type. Nous savons comment nommer nos variables, voyons
maintenant leurs différents types. L'ordinateur aime savoir ce qu'il a dans sa mémoire, il faut
donc indiquer quel type d'élément va contenir la variable que nous aimerions utiliser. Est-ce
un nombre, un mot, une lettre ? Il faut le spécifier.
Voici donc la liste des types de variables que l'on peut utiliser en C++.
Il nous faut indiquer à l'ordinateur, le type de la variable que l'on veut, son nom et enfin sa
valeur. Pour se faire, c'est très simple.
On indique les choses exactement dans cet ordre.
TYPE NOM (VALEUR) ;
On peut aussi utiliser la même syntaxe que dans le langage C :
TYPE NOM=VALEUR;
Exemple :
#include <iostream>
using namespace std;
int main()
{
int age(16);
return 0;
}
10
Que se passe-t-il à la ligne 5 de ce programme ?
L'ordinateur voit que l'on aimerait lui emprunter un tiroir dans sa mémoire avec les propriétés
suivantes :
Il peut contenir des nombres entiers.
Il a une étiquette indiquant qu'il s'appelle âge.
Il contient la valeur 16
Le tableau ci-dessous représente les types de variables avec taille et intervalle :
TYPE NOM ;
11
string nomJoueur;
int nombreJoueurs;
bool aGagne; //Le joueur a-t-il gagné ?
return 0;
}
Afficher la valeur d'une variable
Dans le chapitre précédent, vous avez appris à afficher du texte à l'écran. J'espère que vous
vous souvenez encore de ce qu'il faut faire. Oui, c'est bien ça. Il faut utiliser cout et les
chevrons (<<). Parfait. Parce que pour afficher le contenu d'une variable, c'est la même chose.
A la place du texte à afficher, on met simplement le nom de la variable.
12
Quelques constants caractères :
Les réels
Un réel est composé :
-d’un signe,
-d’une mantisse,
-d’un exposant,
Un nombre de bits est réservé en mémoire pour chaque élément.
Le langage C++ distingue 2 types de réels :
13
– int : entier (16 ou 32 bits, suivant les machines), qui possède les variantes short [int] et
long [int], tous trois pouvant également être déclarés non signés (unsigned),
– float : réel (1 mot machine),
– double: réel en double précision (2 mots machines), et sa variante long double (3 ou 4
mots machine),
2-4-Les instructions d’affectation et expression
L’affectation simple
= affectation
Il faut bien noter que le signe = est l’opérateur d’affectation, et non de comparaison ; cela
prête parfois à confusion, et entraîne des erreurs difficiles à discerner. À noter aussi que
l’affectation est une expression comme une autre, c’est-à-dire qu’elle retourne une valeur. Il
est donc possible d’écrire :
a = b = c+2;
ceci revenant à affecter à b le résultat de l’évaluation de c+2, puis à a le résultat de
l’affectation b = c+2, c’est-à-dire la valeur qu’on a donnée à b. Remarquez l’ordre
d’évaluation de la droite vers la gauche.
Exemple :Test de l'affectation d'une variable à une autre
#include <iostream>
using namespace std;
int main()
{
int a(4), b(5); //Déclaration de deux variables.
cout << "a vaut : " << a << " et b vaut : " << b << endl;
cout << "Affectation !"<< endl;
a = b; //Affectation de la valeur de 'b' à 'a'.
cout << "a vaut : " << a << " et b vaut : " << b << endl;
return 0;
}
14
Code : Console(Exécution)
a vaut : 4 et b vaut : 5
Affectation !
a vaut : 5 et b vaut : 5
Exemple :
15
Exemple 2 :
Opérateur d’opération :
X=a+b ;
Il existe cinq opérations l’addition (+), soustraction (-), la multiplication (*), la division (/),
et le modulo (%).Un petit tableau récapitulatif Le tableau ci-dessous résume les opérateurs
mathématiques.
Soustraction - résultat = a - b;
Multiplication * résultat = a * b;
La division / résultat = a / b;
Exemple1 :
19.0 / 5.0 vaut 3.8,
19 / 5 vaut 3,
19 % 5 vaut 4.
#include <iostream>
using namespace std;
int main()
{
16
double a(0), b(0); //Déclaration des variables utiles
cout << "Bienvenue dans le programme d'addition a+b !" << endl;
cout << "Donnez une valeur pour a : "; //Demande du premier
nombre
cin >> a;
cout << "Donnez une valeur pour b : "; //Demande du deuxième
nombre
cin >> b;
double const resultat(a + b); //On effectue l'opération
cout << a << " + " << b << " = " << resultat << endl; //On
affiche le résultat
return 0;
}
Exemple 3 :
17
Fonctions mathématiques : elles sont déclarées dans <cmath>.il y a notamment les fonctions
suivantes, de paramètre double et de résultat double :
Exemple 4 :
18
Les opérateurs relationnels
Exemple :
Int a=27 ; b=19 ;
a==b ; //cette opération donne la valeur False
a<b ; //cette opération donne la valeur True
Exemple :
Int a ;
Cin >>//pour entrer une valeur pour A
A++
Cout <<A ;// afficher le résultat.
Voici un tableau présentant l’ensemble des opérateurs de C++ (certains ne seront exploités
que dans des chapitres ultérieurs) :
19
20
CHAPITRE 3:
STRUCTURES CONDITIONNELLES ET
BOUCLES
1- INTRODUTION
Une structure de contrôle ou instruction de contrôle sert à contrôler le déroulement d’un
traitement.
Un traitement peut s’exécuter de différentes manières :
Séquentiellement (l’un à la suite de l’autre).
Alternativement (soit l’un soit l’autre ou les autres selon une condition fixée).
21
Il faut savoir qu'il existe plusieurs types de conditions en C++ pour faire des tests, mais la
plus importante qu'il faut impérativement connaître est sans aucun doute la condition if.
2-1- La condition if
Les conditions permettent de tester des variables pour qu'un programme soit capable de
prendre des décisions.
Syntaxe des traitements alternatifs if
L’alternative simple : if (condition)
Séquence
22
#include <iostream>
using namespace std;
int main()
{
int nbEnfants(2);
if (nbEnfants > 0)
{
cout << "Vous avez des enfants, bravo !" << endl;
}
cout << "Fin du programme" << endl;
return 0;
}
Ce code affiche :
Code : Console
Vous avez des enfants, bravo !
Fin du programme
23
L’ordinateur lit d'abord la condition du if et se rend compte que la condition est fausse. On
vérifie si la personne a au moins 1 enfant et ce n'est pas le cas. L'ordinateur "saute" tout ce qui
se trouve entre les premières accolades et tombe sur la ligne du else qui signifie "sinon". Il
effectue donc les actions indiquées après le else.
24
{
cout << "Alors, c'est pour quand le deuxième ?" << endl;
}
else if (nbEnfants == 2)
{
cout << "Quels beaux enfants vous avez la !" << endl;
}
else
{
cout << "Bon, il faut arrêter de faire des gosses maintenant
!" << endl;
}
cout << "Fin du programme" << endl;
return 0;
}
25
Syntaxe des traitements alternatifs switch
.
Case valeur 2 :séquence 2 ;
Case valeur N :séquence N ;
Break ;
Default :séquence ;
}
En théorie, la condition if permet de faire tous les tests que l'on veut. En pratique, il existe
d'autres façons de faire des tests. La condition switch, par exemple, permet de simplifier
l'écriture de conditions qui testent plusieurs valeurs différentes pour une même variable.
Prenez par exemple le test qu'on vient de faire sur le nombre d'enfants :
26
A-t-il 0 enfants ?
A-t-il 1 enfant ?
A-t-il 2 enfants ?
...
On peut faire ce genre de tests avec des if... else if... else, mais on peut faire la même chose
avec une condition switch qui a tendance à rendre le code plus lisible dans ce genre de cas.
Voici ce que donnerait la condition précédente avec un switch :
Code : C++
#include <iostream>
using namespace std;
int main()
{
int nbEnfants(2);
switch (nbEnfants)
{
case 0:
cout << "Eh bien alors, vous n'avez pas d'enfants ?" <<
endl;
break;
case 1:
cout << "Alors, c'est pour quand le deuxieme ?" << endl;
break;
case 2:
cout << "Quels beaux enfants vous avez la !" << endl;
break;
default:
cout << "Bon, il faut arrêter de faire des gosses
maintenant !" << endl;
break;
}
return 0;
}
Cela affiche :
Code : Console
Quels beaux enfants vous avez la !
La forme est un peu différente : on indique d'abord qu'on va analyser la variable
nbEnfants(ligne 9). Ensuite, on teste tous les cas (case) possibles : si ça vaut 0, si ça vaut 1, si
ça vaut 2...
Les break sont obligatoires si on veut que l'ordinateur ne continue pas d'autres tests une fois
qu'il en a vérifié un.
27
Enfin, le default à la fin correspond au else ("sinon") et s'exécute si aucun test précédent n'est
vérifié.
3-LES BOUCLES
Les boucles vous permettent de répéter les mêmes instructions plusieurs fois dans votre
programme. Le principe est le suivant :
La boucle FOR
28
Voici un exemple concret qui affiche des nombres de 0 à 9 :
Code : C++
#include <iostream>
using namespace std;
int main()
{
int compteur(0);
for (compteur = 0 ; compteur < 4 ; compteur++)
{
cout << compteur << endl;
}
return 0;
}
Ce code affiche :
Code : Console
0
1
2
3
On retrouve sur la ligne du for les 3 instructions que je vous ai indiquées :
Une initialisation (compteur = 0) : la variable compteur est mise à 0 au tout début de la
boucle. Notez que ça avait été fait juste la ligne au-dessus donc ce n'était pas vraiment
nécessaire ici.
Une condition (compteur < 4) : on vérifie que la variable compteur est inférieure à 4 à
chaque nouveau tour de boucle.
Une incrémentation (compteur++) : à chaque tour de boucle, on ajoute 1 à la variable
compteur ! Voilà pourquoi on voit s'afficher à l'écran des nombres de 0 à 3.
La boucle while
Syntaxe:
while (condition)
{
/* Instructions à répéter */
}
29
Tout ce qui est entre accolades sera répété tant que la condition est vérifiée.
Exemple de la boucle while
On redemande le nombre d'enfants à l'utilisateur tant que celui-ci est inférieur à 0. Ce genre
de boucle permet de s'assurer que l'utilisateur rentre un nombre correct.
Code : C++
#include <iostream>
using namespace std;
int main()
{
int nbEnfants(-1); // Nombre négatif pour pouvoir rentrer dans
la boucle
while (nbEnfants < 0)
{
cout << "Combien d'enfants avez-vous ?" << endl;
cin >> nbEnfants;
}
cout << "Merci d'avoir indique un nombre d'enfants correct. Vous
en avez " << nbEnfants << endl;
return 0;
}
Code : Console
Combien d'enfants avez-vous ?
-3
Combien d'enfants avez-vous ?
-5
Combien d'enfants avez-vous ?
2
Merci d'avoir indiqué un nombre d'enfants correct. Vous en avez 2
30
Tant que vous mettrez un nombre négatif, la boucle recommencera. En effet, elle teste while
(nbEnfants < 0) c'est-à-dire "Tant que le nombre d'enfants est inférieur à 0". Dès que le
nombre devient supérieur ou égal à 0, la boucle s'arrête et le programme continue après
l'accolade fermante.
La boucle do while
Syntaxe:
Cette boucle est très similaire à la précédente... si ce n'est que la condition n'est analysée
qu'à la fin. Cela signifie que le contenu de la boucle sera toujours lu au moins une première
fois.
do
{
/* Instructions */
} while (condition);
31
Le principe est le même, le programme a le même comportement. Le gros intérêt du do ...
while est qu'on s'assure que la boucle sera lue au moins une fois.
D'ailleurs, du coup, il n'est pas nécessaire d'initialiser nbEnfants à -1 (c'est le principal
avantage que procure cette solution). En effet, ici le nombre d'enfants est initialisé à 0
(comme on a l'habitude de faire), et comme la condition n'est testée qu'après le premier
passage de la boucle, les instructions sont bien lues au moins une fois.
Exemple :
Soit une équation du second degré ax2+bx+c=0
a,b,c sont des nombres réels.
Ecrire un programme qui permet de résoudre cette équation.
Pour trouver les solutions si elles existent il faut :
1-verifier si a=0 dans ce cas la solution est x=-c/b
2-calculer le discriminant D=b2-4ac
Si D=0 alors il existe une solution double x0=-b/2a
Si D>0 alors il existe deux solutions x1=(-b-√ )/2a
X2=(-b+√ )/2a
Si D<0 alors pas de solutions réelles
Code c++ :
#include <iostream>
#include <math.h>// pour l’utilisation de la fonction sqrt
using namespace std;
int main()
{
float a,b,c,x0,x1,x2,D;
cout<<"resolution d’une equation du second degré \n";
cout<<"introduire la valeur de a \n";
cin>>a;
cout<<"introduire la valeur de b \n";
cin>>b;
cout<<"introduire la valeur de c \n";
cin>>c;
if (a==0 && b!=0)
{
32
Cout<< "on obtient une équation du premier degré \n" ;
X0=-c/b ;
Cout<< "la solution de l’équation est : "<<x0<<" \n" ;
}
Else
{
D=(b*b)-4*a*c ;
If (D==0)
{
X0=-b/(2*a);
Cout<< "la solution double de l’équation est : "<<x0<<" \n" ;
}
Else
If (D>0)
{
X1=(-b-sqrt(D))/(2*a) ;
X2=(-b+sqrt(D))/(2*a) ;
Cout<< "deux solutions distinctes de l’équation \n" ;
Cout<< "x1= "<<x1<<" \n" ;
Cout<< "x2= "<<x2<<" \n" ;
}
Else
{
Cout<< "pas de solutions réelles \n" ;
}
}
return 0;
}
33
CHAPITRE 4:
ENTREES / SORTIES
1-INTRODUCTION
Ce chapitre présente les opérations Entrées / Sorties les plus courantes et les plus requises
pour la programmation C ++.
En C++, les entrées-sorties reposent sur les notions de flot et de sur définition d’opérateur que
nous n’aborderons qu’ultérieurement. Les flux d'entrée / sortie de la bibliothèque standard
C++ constituent sans doute l'une des applications les plus intéressantes de la surcharge des
opérateurs. Comme nous allons le voir, la surcharge des opérateurs << et >> permet d'écrire et
de lire sur ces flux de manière très intuitive. Il ne serait pas judicieux cependant d’attendre
que vous ayez étudié ces différents points pour commencer à écrire des programmes
complets. C’est pourquoi dans ce chapitre nous vous présentons ces possibilités d’entrées-
sorties, de manière assez informelle, en nous limitant à ce que nous nommons l’aspect
conversationnel, à savoir :
o la lecture sur l’entrée standard ;
o l’écriture sur la sortie standard.
Un programme qui n'interagit pas du tout avec l'extérieur ne peut présenter aucun intérêt. Il
faut au minimum que le programme puisse écrire un résultat à l'écran ou dans un fichier. Dans
ce but, la technique des flux est utilisée.
34
Définition d’un flux : Un flux est un transfert d’informations, partant d’un émetteur, jusqu’à
un récepteur, qui consomme ces informations (ce flux).
Les entrées et sorties en C++ se font toujours par l'intermédiaire de flots (ou flux), qu'on peut
considérer comme des canaux
- recevant de l'information dans le cas d'un flot de sorties.
- fournissant l'information dans le cas d'un flot d'entrées.
Le flot de sorties standard est cout. Ce flot est connecté par défaut à l'écran.
Le flot d'entrées standard est cin. Ce flot est connecté par défaut au clavier.
Les opérateurs de manipulation des flots, qui permettent le transfert de l'information sont
- << qui permet l'écriture sur un flot de sorties
- >> qui permet la lecture sur un flot d'entrées
En effet, la bibliothèque standard C++ définit dans l'en-tête Iostream des classes
extrêmement puissantes permettant de manipuler les flux d'entrée / sortie. Ces classes
réalisent en particulier les opérations d'entrée / sortie de et vers les périphériques d'entrée et
les périphériques de sortie standards (généralement, le clavier et l'écran). La programmation
des E/S en C++ est particulièrement facile pour la plupart des besoins du programmeur. En
effet, avec les 2 opérateurs '<<' et '>>' et les 2 mots 'cin' et 'cout' on gère les dialogues avec
le clavier et l’écran ; et avec 2 mots supplémentaires, 'ofstream' et 'ifstream' on accède aux
fichiers, car pour ces deux classes, l'ouverture est réalisée dans le constructeur et la fermeture
dans le destructeur.
35
o istrstream qui dérive de istream
o ostrstream qui dérive de ostream
Signalons les quatre flots mis à la disposition du programmeur, déclarés dans iostream.h:
extern istream_withassign cin; // Entrée par défaut (assignée au clavier)
extern ostream_withassign cout; // Sortie par défaut (assigné à la console)
extern ostream_withassign cerr; // Sortie par défaut des erreurs (idem)
extern ostream_withassign clog; // Sortie par défaut des journaux (idem)
Les entrées sont les données que l’utilisateur fournit à un programme durant l’exécution, par
l’intermédiaire du clavier ou d’un fichier. Les sorties sont les résultats que le programme
fournit à l’utilisateur durant l’exécution, par l’intermédiaire de l’écran ou d’un fichier. On
utilise les instructions d’entrée-sortie du C++ parce qu’elles sont plus simples que celles du C.
Il faut, dans tous les cas, ajouter au début du fichier contenant le programme :
Namespaces.
Un problème classique en C est le fait que toutes les déclarations globales partagent le
même espace de nommage. Cela peut poser problème si, par exemple, vous souhaitez
utiliser deux bibliothèques déclarant une fonction max(). Le C++ utilise un système
d’espace de nommage (namespace) pour éviter cela. Toutes les fonctions du C++ sont
donc inclues dans le namespace std. En pratique, pour accéder à un élément de la
bibliothèque standard, il faut ajouter std:: devant pour signaler que l’on cherche à accéder
à un élément du namespace std. Lorsque un namespace est fréquemment utilisé dans un
36
fichier, il est possible d’ajouter la déclaration using namespace std; pour éviter d’avoir à
ajouter std:: partout. Cependant, il ne faut jamais faire cela dans un fichier header !
#include<iostram>
3-1-LIRE AU CLAVIER
Le flux cin
Syntaxe :
cin >> valeur1>> ... >> valeurn;
-cin est le flux d’entrée du clavier
– ">>" permet d’orienter les valeurs tapées dans le clavier vers les variables valeuri
– cin permet de lire des valeurs de tous les types.
En pratique :
– Lors de l’exécution d’un programme, si on rencontre une instruction cin, l’exécution
s’arrête en attente de la saisie des valeurs dans le clavier. Selon la syntaxe précédente, il
faudra saisir n valeurs val i espacées par des espaces, des tabulations ou des sauts de ligne. Il
faudra terminer la saisie par un saut de ligne.
Le programme va affecter à chaque variable valeuri la valeur val i:(valeuri=vali)
Exemples
Code c++:
#include <iostream.h>
int main ()
{
int n;
float x;
char t[80+1];
do
{
cout << "donner un entier, une chaîne et un flottant : ";
cin >> n >> t >> x;
cout << "merci pour " << n << ", " << t << " et " << x << "\n";
}
while (n);
return 0;
}
Exécution:
37
donner un entier, une chaîne et un flottant : 15 bonjour 8.25
merci pour 15, bonjour et 8.25
donner un entier, une chaîne et un flottant : 15
bonjour
8.25
merci pour 15, bonjour et 8.25
donner un entier, une chaîne et un flottant : 0 bye 0
merci pour 0, bye et 0
3-2-AFFICHER à L’ECRAN
Le flux cout
Pour écrire le contenu de n'importe quelle variable a l'écran, on utilise l'objet cout qui est une
instance de la classe ostream_withassign définie dans la libraire de flux d'entrée-sortie
iostream (io signifie input-output, stream signifie flux). Le flux cout doit être vu comme un
« tube » (un pipe en anglais) qui relie le programme avec l'écran.
Pour afficher le contenu d'une variable à l'écran, on procède comme suit :
Syntaxe :
cout << expr1<< ... << exprn<< endl;
Exemple 1
int main()
{
cout << "bonjour"; // équivalent à printf("bonjour"); du langage C
return 0;
}
- cout est un flot de sorties prédéfini associé à la sortie standard (stdout du C).
- << est un opérateur dont l’opérande de gauche (cout) est un flot et l’opérande de droite, une
expression de type quelconque.
L’instruction "cout << …" précédente peut être interprétée comme ceci : le flot cout reçoit la
38
valeur "bonjour".
Exemple 2
#include <iostream.h>
int main()
{
int n = 19;
char c = 'b';
char *ch = "souad";
double x = 2018.3456789;
valeur de n : 19
valeur de c : b
chaîne ch : souad
valeur de x : 2018.3456789
4-CAS DES CHAINES DE CARACTERES
Les chaines de caractères sont un groupe de lettres et permettent de représenter des mots,
phrases, etc. Une chaine de caractère est un tableau de char dont la dernière valeur est égale la
valeur 0 (zéro). En C++ il existe deux manières de gérer les chaines de caractères
_ un tableau de caractère : char ch[50];
_ un objet : stringst;
#include<iostream>
usingnamespacestd;
int main(intargc,char*argv[])
{
inti;
cout<<"ChainedeCaracteres:";
charch[50];
cin>>ch;
39
cout<<"Lachaineest:"<<ch<<endl;
for(i=0;ch[i]!=0 ;i++) //jusqu’alavaleur0
cout<<"’"<<ch[i] <<"’";
cout<<endl;
cout<<"String:";
stringst; cin>>st;
cout<<"Lestringest:"<<st<<endl;
for(i=0;i<[Link]() ;i++) //permet de connaitre le nombre de caracteres
cout<<"’"<<st[i] <<"’";
cout<<endl;
}
Si on souhaite demander à l’utilisateur d’entrer une chaine comportant des espaces,
l’utilisation du code suivant est nécessaire (même recommandé dans de nombreux cas pour
éviter les failles de type buffer-overflow).
charch[50];
[Link](ch,50);
Avec un object string ceci est possible grâce au code suivant (utilisation de la fonction globale
getline: ajouter #include<string> ):
stringstr;
getline(cin,str);
40
CHAPITRE 5:
POINTEURS ET TABLEAUX
1- TABLEAUX
Ils existent deux sortes de tableaux différents. Ceux dont la taille est fixée les tableaux
statiques et ceux dont la taille peut varier, les tableaux dynamiques.
1-1- Tableau statique
Un tableau est une zone continue en mémoire, constituée de cellules contenant des données
toutes de même type ou est un ensemble ordonné d’une taille fixe de plusieurs variables du
même type.
Forme de la déclaration d’un tableau statique
41
}
On retrouve nos deux zones mémoires avec leurs étiquettes, mais cette fois, chaque zone est
découpée en cases. Trois cases pour le tableau anglesTriangle et cinq cases pour le tableau
meilleurScore. Pour l'instant toutes ces cases ne sont pas initialisées. Leur contenu est donc
quelconque.
42
meilleursScores[4] = 31415; //Remplissage de la cinquieme case
Parcourir un tableau
Le gros point fort des tableaux, c'est qu'on peut les parcourir en utilisant une boucle. On peut
ainsi effectuer une action sur chacune des cases d'un tableau l'une après l'autre. Par exemple
afficher le contenu des cases.
On connaît à priori le nombre de cases du tableau, on peut donc utiliser une boucle for. Nous
allons pouvoir utiliser la variable i de la boucle pour accéder au ième élément du tableau.
C'est fou, on dirait que c'est fait pour !
43
notes[5] = 15;
double moyenne(0);
for(int i(0); i<nombreNotes; ++i)
{
moyenne += notes[i]; //On additionne toutes les notes
}
//En arrivant ici, la variable moyenne contient la somme des
notes (79.5)
//Il ne reste donc qu'a divisé par le nombre de notes
moyenne /= nombreNotes;
cout << "Votre moyenne est : " << moyenne << endl;
return 0;
}
Code : Console : Exécution
Votre moyenne est : 13.25
Exemple 2 :
Code : C++
#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.
• 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
44
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
Exemple 3:
Voici un programme qui permet d’entrer des entiers dans un vecteur de 6 éléments et de
calculer la somme de ses éléments ?
Code C++
#include <iostream>
using namespace std;
int main()
{
Int tab[6];
45
Int i;
Int som=0;
For(i=1;i<=5;i++)
{
cout<<"introduire un entier dans le tableau,tab["<<i<<"]=";
cin>>tab[i];
som=som+tab[i];
}
cout<<"la somme des éléments du tableau est "<<som<<"\n";
return 0;
}
La première différence se situe au tout début de votre programme. Il faut ajouter la ligne
#include <vector> pour utiliser ces tableaux.
vector<type> nom(VectTaille);
Par exemple pour un tableau de 5 entiers, on écrit :
Code : C++
#include <iostream>
#include <vector> //Ne pas oublier !
using namespace std;
int main()
{
vector<int> tableau(5);
return 0;
}
La déclaration était très différente des tableaux statiques. Par contre là, c'est exactement
identique. On utilise à nouveau les crochets et la première case possède aussi le numéro 0.
Exemple :
Code : C++ - Remplissage d'un tableau
46
int const nombreMeilleursScores(5); //La taille du tableau
vector<int> meilleursScores(nombreMeilleursScores); //Déclaration
du tableau
meilleursScores[0] = 118218; //Remplissage de la première case
meilleursScores[1] = 100432; //Remplissage de la deuxième case
meilleursScores[2] = 87347; //Remplissage de la troisième case
meilleursScores[3] = 64523; //Remplissage de la quatrième case
meilleursScores[4] = 31415; //Remplissage de la cinquième case
Changer la taille
Entrons maintenant dans le vif du sujet. Faire varier la taille d'un tableau. Commençons par
ajouter des cases à la fin d'un tableau. Il faut utiliser push_back(). On écrit le nom du tableau,
suivi d'un point et du mot push_back avec entre parenthèses la valeur qui va remplir la
nouvelle case.
Code : C++
vector<int> tableau(3,2); //Un tableau de 3 entiers valant tous 2
tableau.push_back(8); //On ajoute une 4ème case au tableau. Cette case contient la valeur .
Une case supplémentaire a été ajoutée au bout du tableau. Tout se fait de manière
automatique.
On peut supprimer la dernière case d'un tableau en utilisant la fonction pop_back() de la
même manière que push_back(). Sauf qu'il n'y a rien à mettre entre les parenthèses.
Code : C++
vector<int> tableau(3,2); //Un tableau de 3 entiers valant tous 2
tableau.pop_back(); //Et hop ! Plus que 2 cases.
tableau.pop_back(); //Et hop ! Plus qu'une case.
47
Il nous reste quand même un petit problème à régler. Comme la taille peut changer, on ne sait
pas combien d'éléments un tableau contient de manière certaine. Heureusement, il y a une
fonction pour ça. C'est la fonction size(). En faisant [Link](), on récupère un entier
correspondant au nombre d'éléments de tableau.
Code : C++
vector<int> tableau(5,4); //Un tableau de 5 entiers valant tous 4
int const taille([Link]()); //Une variable pour contenir la taille du tableau
//La taille peut varier mais la valeur de cette variable ne changera pas.
//On utilise donc une constante.
//A partir d'ici, la constante 'taille' vaut donc 5
48
Pour déclarer un tel tableau, il faut indiquer les dimensions les unes après les autres entre
crochets.
type nomTableau[tailleX][tailleY]
Exemple :
int tableau[5][4];
Pour accéder à une case de notre grille, il faut indiquer la position en X et en Y de la case
voulue. Par exemple tableau[0][0] accède à la case en-bas à gauche de la grille. tableau[0][1]
correspond à celle qui se trouve juste en-dessus, alors que tableau[1][0] se situe directement à
sa droite.
2- 2-Les pointeurs
2-2-1- Adresse
Lorsque l'on déclare une variable, l'ordinateur nous prête une place dans sa mémoire et y
accroche une étiquette portant le nom de la variable.
Code : C++
int main()
49
{
int ageUtilisateur(16);
return 0;
}
On pouvait donc représenter la mémoire utilisée dans ce programme sur le schéma suivant :
L'important est que chaque variable possède une seule adresse. Et chaque adresse correspond
à une seule variable. L'adresse est donc un deuxième moyen d'accéder à une variable. On peut
accéder à la case jaune du schéma par deux chemins différents :
On peut passer par son nom (l'étiquette) comme on sait déjà le faire...
Mais on peut aussi accéder à la variable grâce à son adresse (son numéro de case)..
On pourrait alors dire à l'ordinateur "Affiche moi le contenu de l'adresse 53768"
50
Afficher l'adresse
En C++, le symbole pour obtenir l'adresse d'une variable est l'esperluette (&). Si je veux
afficher l'adresse de la variable ageUtilisateur, je dois donc écrire &ageUtilisateur.
Essayons.
Code : C++
#include <iostream>
using namespace std;
int main()
{
int ageUtilisateur(16);
cout << "L'adresse est : " << &ageUtilisateur << endl; //
Affichage de l'adresse de la variable
return 0;
}
Code : Console
L'adresse est : 0x22ff1c
L'esperluette veut dire "adresse de". Donc cout << &a; se traduit en français par "Affiche
l'adresse de la variable a".
2-2-2- Les pointeurs définition
Un pointeur est une variable qui contient l'adresse d'une autre variable.
Une variable pointeur est destinée à manipuler des adresses d’informations d’un type donné.
Déclarer un pointeur
Pour déclarer un pointeur, il faut, comme pour les variables, deux choses :
Un type
Un nom
Pour le nom, il n'y a rien de particulier à signaler. Les mêmes règles que pour les variables
s'appliquent. Ouf !
Le type d'un pointeur a une petite subtilité. Il faut indiquer quel est le type de variable dont on
veut stocker l'adresse et ajouter une étoile (*).
Exemple :
Code : C++ - Déclaration d'un pointeur
int *pointeur;
Ce code déclare un pointeur qui peut contenir l'adresse d'une variable de type int.
Exemple :
Code : C++ - Déclaration de pointeurs
double *pointeurA; //Un pointeur qui peut contenir l'adresse d'un nombre a virgule
unsigned int *pointeurB; //Un pointeur qui peut contenir l'adresse d'un nombre entier positif
string *pointeurC; //Un pointeur qui peut contenir l'adresse d'une chaîne de caractères
51
vector<int> *pointeurD; //Un pointeur qui peut contenir l'adresse d'un tableau dynamique de
nombres entiers
int const *pointeurE; //Un pointeur qui peut contenir l'adresse d'un nombre entier constant
Maintenant qu'on a la variable, il n'y a plus qu'à mettre une valeur dedans. Vous savez déjà
comment obtenir l'adresse d'une variable (rappelez-vous du &). Allons-y !
Code : C++
int main()
{
int ageUtilisateur(16); //Une variable de type int.
int *ptr(0); //Un pointeur pouvant contenir
l'adresse d'un nombre entier.
ptr = &ageUtilisateur; //On met l'adresse de 'ageUtilisateur'
dans le pointeur 'ptr'.
return 0;
}
La ligne 6 est celle qui nous intéresse. Elle écrit l'adresse de la variable ageUtilisateur dans le
pointeur ptr. On dit alors que le pointeur ptr pointe sur ageUtilisateur.
Afficher l'adresse
Comme pour toutes les variables, on peut afficher le contenu d'un pointeur.
Code : C++
#include <iostream>
52
using namespace std;
int main()
{
int ageUtilisateur(16);
int *ptr(0);
ptr = &ageUtilisateur;
cout << "L'adresse de 'ageUtilisateur' est : " <<
&ageUtilisateur << endl;
cout << "La valeur de pointeur est : " << ptr << endl;
return 0;
}
Code : Console
L'adresse de 'ageUtilisateur' est : 0x2ff18
La valeur de pointeur est : 0x2ff18
Le but des pointeurs est d’accéder à une variable sans passer par son nom. Voici
comment faire. Il faut utiliser l'étoile (*) sur le pointeur pour afficher la valeur de la
variable pointée.
Code : C++
int main()
{
int ageUtilisateur(16);
int *ptr(0);
ptr= &ageUtilisateur;
cout << "La valeur est : " << *ptr << endl;
return 0;
}
En faisant cout << *ptr, le programme va effectuer les étapes suivantes :
1. Aller dans la case mémoire nommée ptr.
2. Lire la valeur enregistrée.
3. "Suivre la flèche" pour aller à l'adresse pointée.
4. Lire la valeur stockée dans la case.
5. Afficher cette valeur. Ici, ce sera bien sûr 16 qui sera affiché.
En utilisant l'étoile, on accède à la valeur de la variable pointée. C'est ce qui s'appelle
déréférencer un pointeur.
L'allocation dynamique
Pour demander manuellement une case dans la mémoire, il faut utiliser l'opérateur new.
53
new va demander une case à l'ordinateur et renvoyer un pointeur pointant vers cette case.
Code : C++
int *pointeur(0);
pointeur = new int;
*pointeur = 2; //On accède à la case mémoire pour en modifier la Valeur
La deuxième ligne demande une case mémoire pouvant stocker un entier et l'adresse de cette
case est stockée dans le pointeur.
Une fois allouée manuellement, la variable s'utilise comme n'importe quelle autre. On doit
juste se rappeler qu'il faut y accéder par le pointeur en le déréférençant.
La case sans étiquette est maintenant remplie. La mémoire est donc dans l'état suivant :
Libérer la mémoire
Une fois que l'on a plus besoin de la case mémoire, il faut la rendre à l'ordinateur. Cela se fait
via l'opérateur delete.
Code : C++
int *pointeur(0);
pointeur = new int;
delete pointeur; //On libère la case mémoire
La case est alors rendue à l'ordinateur qui pourra l'utiliser pour autre chose. Le pointeur, lui,
existe toujours. Et il pointe toujours sur la case mais vous n'avez plus le droit de l'utiliser.
54
L'image est très parlante. Si l'on suit la flèche, on arrive sur une case qui ne nous appartient
pas. Il faut donc impérativement empêcher ça. Imaginez que cette case soit soudainement
utilisée par un autre programme ! Vous risqueriez de modifier les variables de cet autre
programme.
Il est donc essentiel de supprimer cette "flèche" en mettant le pointeur à l'adresse 0 après
avoir utilisé delete. Ne pas le faire est une source très courante de plantage des programmes.
Code : C++
int *pointeur(0);
pointeur = new int;
delete pointeur; //On libère la case mémoire
pointeur = 0; //On indique que le pointeur ne pointe vers plus rien
Exemple
Terminons cette section avec un exemple complet : un programme qui demande son âge à
l'utilisateur et qui l'affiche en utilisant un pointeur.
Code : C++
#include <iostream>
using namespace std;
int main()
{
int* pointeur(0);
pointeur = new int;
cout << "Quel est votre age ? ";
cin >> *pointeur; //On écrit dans la case mémoire pointée par
le pointeur 'pointeur'
cout << "Vous avez " << *pointeur << " ans." << endl; //On
utilise à nouveau *pointeur
delete pointeur; //Ne pas oublier de libérer la mémoire
pointeur = 0; //Et de faire pointer le pointeur vers rien
55
return 0;
}
Ce programme est plus compliqué que sa version sans allocation dynamique ! C'est vrai. Mais
on a le contrôle complet sur l'allocation et la libération de la mémoire.
Dans la plupart des cas, ce n'est pas utile de le faire. Mais vous verrez plus tard que, pour faire
des fenêtres, la bibliothèque Qt utilise beaucoup new et delete. On peut ainsi maîtriser
précisément quand une fenêtre est ouverte et quand on la referme par exemple.
56
ANNEXE
Quelques fichiers d’entêtes du C++
Types de variables
57
Mots clés réservés de C++
58
Les fonctions mathématiques <math.h>
Fonctions trigonométriques et hyperboliques :
Fonctions diverses :
59