Post on 19-Jun-2022
1
++- 1M. BENJELLOUN : 2019 UMONS
Mohammed BENJELLOUN
Service d’Informatique
Faculté Polytechnique de Mons
Mohammed.Benjelloun@umons.ac.be
2019
++- 2M. BENJELLOUN : 2019 UMONS
2019
2
++- 3M. BENJELLOUN : 2019 UMONS
Objectifs
Être capable de construire des bons programmes
Des programmes : corrects, efficaces, robustes, relativement faciles à comprendre, à modifier et à maintenir.
Qualités attendues d'un programme
Clarté, Simplicité, Efficacité, Modularité, Extensibilité.
Programmer de manière modulaire
Lors des séances d'exercices, où la présence est obligatoire commeaux TPs, un complément de matière sera abordé. On ne peut doncconsidérer, le syllabu et ce document comme complets.
Pré-requis : Aucun
++- 4M. BENJELLOUN : 2019 UMONS
Architecture claire
Algorithmes
Structures de données
Réutilisabilité
Tests de robustesse
Documentation
“Comment organiser au mieux l’informationdans un programme ?”
Qualité d’un programme
Non
Oui
Menu
Début programme
Bon Choix
Saisie()
Affichage()
(1) (2) (3)
(1) OK
Oui
Non
…
…
(4)
Fin
Tri()
Affichage()
3
++- 5M. BENJELLOUN : 2019 UMONS
C'est en forgeant que l'on devient forgeron, et c'est en programmant que euh... Peut-être …
Codes sources
C++ Programmes
Transp.
Énoncé des TPs
Préparez les TPs
Syllabus.pdf
Document
‘’Environnement logiciel’’
Vidéos
120 tests formatifs sur C++
Note relative à l’organisation de l’examen pratique
…
.
Utilisation du débuggeur
https://moodle.umons.ac.be/
++- 6M. BENJELLOUN : 2019 UMONS
Le langage C++ !!
Qu'est-ce que c’est ?D'où vient-il ?Pourquoi utiliser C++ ?Que peut-on faire avec et à quoi ça sert ?De quoi ai-je besoin pour programmer en C++ ?
Caractéristiques du C++
• Langage structuré: tâches d'un programme en blocs.• Programmes efficaces : génère un code compact et rapide…• Modulaire : découpe en modules• Objets : meilleure qualité de programmation.
4
++- 7M. BENJELLOUN : 2019 UMONS
Moi, ingénieur… que vais-je bien pouvoir faire ?
Pour commencer, j’aimerais programmer: Y = X2, Z = X3 et
#include <iostream> // pour cout et cin#include <cmath> // pour sqrt( )using namespace std;
void main() {int X, Y, Z ; // variablesfloat racine;
cout << " ??valeur de X = ";cin >> X;
Y= X * X ; // X²Z= Y * X ; // X³racine = sqrt(X);
cout << "La racine de" << X << " est " << racine << endl;cout << " Y = " << Y << " et Z = " << Z ;
}
++- 8M. BENJELLOUN : 2019 UMONS
Les entrées /sorties : cin et cout
• cout, le flux standard de sortie, habituellement associé à l'écran,
Syntaxe : cout << expression << expression … ;
• cin, le flux standard d’entrée, habituellement associé au clavier,
Syntaxe : cin >> valeur >> valeur >> valeur … ;
#include <iostream>
using namespace std;
void main() { // ou int main()
cout <<" Salut a vous tous" << endl;
cout << " oui tous " ;
} // ou return 1; } si int main()
endl signifie un saut de ligne
:
7
Pour commencerTout programme doit avoir un point d’entrée nommé main()
// Ceci est un commentaire sur 1 seule ligne
5
++- 9M. BENJELLOUN : 2019 UMONS
Directives du préprocesseur
Une directive préprocesseur est une directive de compilation (précédées par un #)
Gestion des Entrées-Sorties standard <iostream>
Fonctions mathématiques <cmath>
Traitement de chaînes de caractères <string>
Contrôler les paramètres d'affichage <iomanip>
#include <cmath>
++- 10M. BENJELLOUN : 2019 UMONS
Fonctions mathématiques spéciales
C++11
Nom et doc de la fonction Prototype de la fonction Expression mathématique
Polynômes de Laguerre
généralisés
double assoc_laguerre( unsigned n,
unsigned m, double x ) ;
Polynômes de Legendre
généralisés
double assoc_legendre( unsigned l,
unsigned m, double x ) ;
Fonction bêta double beta( double x, double y ) ;
https://fr.wikipedia.org/wiki/C%2B%2B11
Fonctions de Bessel
cylindriques du premier
genre
double cyl_bessel_j( double nu,
double x ) ;
6
++- 11M. BENJELLOUN : 2019 UMONS
cout <<"Qu'il est agreable d'utiliser "
<<"cout en\t C++,\nlorsqu'on l'utilise " <<endl << "\t\tproprement";
Résultat :Qu'il est agreable d'utiliser cout en C++,
lorsqu'on l'utilise
proprement
Caractères Signification CODE ASCII
(hexadécimal)
\n ou endl Génère une nouvelle ligne (newline) 0x0A
\t Tabulation horizontale 0x09
\v Tabulation verticale 0x0B
\b Retour d’un caractère en arrière (backspace) 0x08
\r Retour chariot (return) 0x0D
\f Saut de page (form feed) 0x0C
..
\t
\t \t
setw(x) : la prochaine sortie sera sur une largeur de x
setfill(c) : utilisera c comme caractère de remplissage.
++- 12M. BENJELLOUN : 2019 UMONS
#include<iostream>using namespace std;#include <windows.h>
void Color(int couleurDuTexte) {HANDLE H=GetStdHandle(STD_OUTPUT_HANDLE);SetConsoleTextAttribute(H, couleurDuTexte);
}
void main() {Color(10); //Couleur du texte : VERT.
cout << "Salut a vous !!!" << endl;
Color(4); //Couleur du texte : ROUGE.cout << "Tous !!!" << endl;
system("pause");}
Les couleurs :________________________________
| 0 : Noir | 1 : Bleu foncé || 2 : Vert foncé | 3 : Turquoise | | 4 : Rouge foncé | 5 : Violet | | 6 : Vert caca d'oie | 7 : Gris clair || 8 : Gris foncé | 9 : Bleu fluo | | 10 : Vert fluo | 11 : Turquoise || 12 : Rouge fluo | 13 : Violet || 14 : Jaune | 15 : Blanc |---------------------------------------------------
Salut a vous !!!Tous !!!
7
++- 13M. BENJELLOUN : 2019 UMONS
setw(int) : impose la largeur d'affichage à int caractères. Texte et nombres sont alignés à droite.
setprecision(int): impose le nombre de caractères du nombre affiché.
setfill(char): remplace les espaces précédant le nombre par le caractère char.
#include <iostream>
#include <iomanip>
using namespace std;
void main(){
const double Pi = 3.14159265359 ;
cout << Pi << endl ;
cout << setprecision(9) << Pi << endl ;
cout << setprecision(2) << Pi << endl ;
cout << setw(10) << setprecision(2) << Pi << endl ;
cout << setw(15) << setfill('.') << setprecision(9) << Pi << endl ;
}
3.141593.141592653.1
3.1.....3.14159265
Formatage de la présentation → écran
++- 14M. BENJELLOUN : 2019 UMONS
Identificateurs
Les identificateurs nomment les objets C++ (fonctions, variables ...).
Le C++ distingue les minuscules des majuscules.
Exemple: ab, Ab, ABsont des identificateurs valides et tous différents.
Identificateurs valides :
xx y1 somme_5 _position Noms Programme_1
Identificateurs invalides :
3eme commence par un chiffre
x#y caractère non autorisé (#)
no-commande caractère non autorisé (-)
taux change caractère non autorisé (espace)
8
++- 15M. BENJELLOUN : 2019 UMONS
Un identificateur ne peut pas être un mot réservé du langage :
Les mots réservés du langage C++
doivent être écrits en minuscules.
++- 16M. BENJELLOUN : 2019 UMONS
Variables : déclarations,
Syntaxe : Type identificateur1, id2,…. ;
char c1, c2, c3;
int i, j, var_ent;
float f, variable;
Exemple:
initialisations
int i=9; ou int i;
i=9;
char c1= 'A'; ou char c1;
c1= 'A';
Constantes : déclarations + initialisations
Syntaxe : const Type identificateur1=Val1, identificateur2=Val2, …,…. ;
const char c = 'A';
const int i=5, var_ent=8;
Exemple: const int i;
i= 5;
L’initialisation des constantes est obligatoire lors de leur déclaration.
9
++- 17M. BENJELLOUN : 2019 UMONS
#include <iostream>
using namespace std;int Somme(int x, int y);
void main(void) {
int Som;
Som = Somme(7,9); //appel de la fonction
if ( Som > 10 ) {
cout <<" Som > 10 "<< Som<< endl;
}
else {cout <<" Som <= 10 "<< Som;
}
int Somme(int x, int y) { /* Définition de
la fonction */
int S;
S= x+y;
return S ;
}
Directives du préprocesseur : accès avant la compilation
Programme
principal
Déclarations
TraitementsDonnéesStructures de contrôleCommentaires
Structure d'un programme C++ : exemple
++- 18M. BENJELLOUN : 2019 UMONS
Indenter = lisibilité
Prenez l'habitude de respecter (au moins au début) les règles :
- une accolade est seule sur sa ligne,
- { est alignée sur le caractère de gauche de la ligne précédente,
- } est alignée avec l'accolade ouvrante correspondante,
- après { , on commence à écrire deux caractères plus à droite.
#include <Lib1>
#include <Lib2>
using namespace std;
void main(void)
{ /*main*/
instruction;
instruction;
{
instruction;
{
instruction;
}
}
instruction;
} /* fin main*/
Fonctionnement :- Tapez et sauvegardez le programme,- Compilez le programme,- Exécutez le programme.
10
++- 19M. BENJELLOUN : 2019 UMONS
Les opérateurs arithmétiques
Le C++ propose les opérateurs suivants :
+ addition- soustraction* multiplication/ division% modulo (reste de la division entière )
% ne peut être utilisé qu'avec des entiers
7/2
7.0/2 7/2.0 7.0/2.0
3
3.5
…void main() {
int i = 6, j = 4, k;float f = 6.0, g = 4.0, h;
k = i / j; // k= 6/4 = 1h = f / g; // h = 6.0/4.0 = 1.5h = i / j; // h = 6/4 = 1.0
}
Modulo : C=A%B;
C = 4%2 = 0; 5%2 = 1; 8%3= 2;
C=A%2 Si C=0 alors A est pair sinon(=1) A est impair
++- 20M. BENJELLOUN : 2019 UMONS
Comparaisons< plus petit
<= plus petit ou égal
> plus grand
>= plus grand ou égal
== égal
!= différent
Les opérateurs logiques
&& et
|| ou (non exclusif)
! non
Contractions d'opérateurs
+= -= *= /= %=
&= |= ^= <<= >>=
a += 15;
a = a + 15;
i *= j + 5;
i = i * (j + 5);!
Le résultat d'une expression logique est un
booléen. Il vaut true si elle est vraie et false sinon.
Réciproquement, toute valeur non nulle est considérée
comme vraie et la valeur nulle comme fausse.
!
Incrément et décrément
Pour
++ incrément : i++ ou ++i
est équivalent à i += 1 ou i = i + 1
- - décrément
int i = 5, j = 4;
char lettre = 'B';
i++; // i vaudra 6
--j; // j vaudra 3
++i; // i vaudra 7
lettre++; // lettre vaudra C
lettre --; // lettre vaudra B
11
++- 21M. BENJELLOUN : 2019 UMONS
#include <iostream>
using namespace std;
void main() {
int x=5;
float y;
const int W = 6 ;
cout <<" X= " << x;
cout << " y = x/2.0";
cout << " Z = " << z;
cout << " W = " << W +1 ;
W=W+1;
cout << " W = " << W;
}
++- 22M. BENJELLOUN : 2019 UMONS
Les structures de contrôle
Alternative: if-else
Itérations: for, while, do-while
Rupture de Contrôle: break, continue, return …
Choix Multiple: switch-case
Bloc 1
d’instructions
Bloc 2
d’instructions
oui non
Suite du programme
oui non
Suite du
programmeBloc
d’instructions
Condition
vraie
oui
non
Bloc
d’instructions
programme
Conditionvraie
Suite du programme
programme
Condition
vraie
if-else while
do-while
12
++- 23M. BENJELLOUN : 2019 UMONS
Les décisions - if … else
if (Condition vraie)
{
BLOC 1 D'INSTRUCTIONS
}
else
{
BLOC 2 D'INSTRUCTIONS
}
Bloc 1
d’instructions
Bloc 2
d’instructions
oui non
Suite du programme
programme
Condition
vraie
if (Condition vraie) {
instruction 1;
instruction 2;
}
else {
instruction 3;
instruction 4;
}
Bloc 1
d’instructions
oui non
Suite du programme
Condition
vraie
if (Condition vraie)
{
instruction 1;
instruction 2;
instruction 3;…
instruction N;
}
if (Condition vraie)
instruction 1;
if ( temperature > 70.0)
cout << " Alarme "<<endl;
if (Condition vraie)
instruction A;
else
instruction B;
if (a<b)min=a;
elsemin=b;
if (i) if (i != 0)
++- 24M. BENJELLOUN : 2019 UMONS
if ( <expr1> )
<bloc1>
else if (<expr2>)
<bloc2>
else if (<expr3>)
<bloc3>
else if (<exprN>)
<blocN>
else <blocN+1>
if ( <expr1> )
<bloc1>
else if (<expr2>)
<bloc2>
else if (<expr3>)
<bloc3>
else if (<exprN>)
<blocN>
else <blocN+1>
if emboîtés
◼ else est associé avec le if le plus proche
if(i >= 0)
if(i > 1000) cout<<" i > 1000 ";
else cout<<" i < 0 \n";
if(i >= 0) {
if(i > 1000) cout<<" i > 1000 ";
} else cout<<" i < 0 \n";
13
++- 25M. BENJELLOUN : 2019 UMONS
Les itérations – for
#include <iostream> using namespace std;void main() {int nb_f=0;
action;nb_f++;
action;nb_f++;
action;nb_f++;…
}
#include <iostream> using namespace std;void main() {int nb_f=200;
action;nb_f--;
action;nb_f--;
action;nb_f--;…
}
for (nb_f = 0; nb_f <30; nb_f++) {
action;
}
for (nb_f = 200; nb_f >0; nb_f--) {
action;
}
++- 26M. BENJELLOUN : 2019 UMONS
for( ; ; )
{
............;
............;
............;
}
Les itérations – for
for( initialisation ; (Condition vraie); itération )
{
/* liste d'instructions */
}
int i, j;
float K;
for(i = 0, j = 2, k = 7.5 ; (i < 20) &&(j==2); i++, k-=0.2)
int i,j;
for (i = 0; i <3; i++) {
cout<< "i = " << i << endl;
}
cout <<endl<<endl;
for(j = 5; j > 0; j- -)
cout<< "j = " << j << endl;
i = 0
i = 1
i = 2
j = 5
j = 4
j = 3
j = 2
j = 1
boucle infinie
14
++- 27M. BENJELLOUN : 2019 UMONS
#include <iostream>
using namespace std;
void main() {
for (char lettre = 'A'; lettre <= 'M'; lettre++)
cout<<lettre;
cout<<endl;
for (float pourcent = 0.0; pourcent < 0.5; pourcent += 0.1)
cout<<pourcent<<endl;
for (int i=2; i <= 3; i++) {
cout << " Table de " << i << " :" << endl;
for (int j=0; j <= 3; j++) {
cout << " " << i << " * " << j << " = " << i*j << endl;
}
}
}
ABCDEFGHIJKLM
0
0.1
0.2
0.3
0.4
Table de 2 :2 * 0 = 02 * 1 = 22 * 2 = 42 * 3 = 6
Table de 3 :3 * 0 = 0 …
++- 28M. BENJELLOUN : 2019 UMONS
Nous considérons un circuit électrique. Quand l’interrupteur ‘Int’ est dans la position de la Fig (X=1), le générateur de tension ‘G’ allume l’ampoule ‘X’ (X=true ou X = 1). Quand l’interrupteur s’ouvre, ‘X’ s’éteint (X=false ou X = 0).
#include <iostream>using namespace std;
void main() {bool x = 1;cout << " Test : X = " << x << endl;cout << "--------------------------"<< endl;for (int i=0; i < 6 ; i++ ) {
x= 1-x ; // x = ! x ou x=x%2
cout << " X = " << x << endl;}
}
Test : X = 1--------------
X = 0 X = 1 X = 0 X = 1 X = 0 X = 1
Afin de simuler le clignotement d’une ampoule (X), complétez le code de sorte que l’exécution du programme fournisse les résultats ci-dessous (en rouge):
15
++- 29M. BENJELLOUN : 2019 UMONS
La boucle TANT QUE ... FAIRE ...
Boucle pré-testée
Il s'agit de l'instruction while :
tant que (expression vraie)
faire{ BLOC D'INSTRUCTIONS }
Organigramme:
while (Condition vraie){
............; /* bloc d'instructions */
............;
............;
}
Le test se fait d'abord, le bloc
d'instructions n'est pas forcément exécuté.
Syntaxe:
tant que, pas jusqu’à ce que!
oui non
Suite du
programme
Condition
vraie
Bloc 1
d’instructions
++- 30M. BENJELLOUN : 2019 UMONS
i=1;
while(i<5) {
cout<<"Interieur " <<i << endl;
i++;
}
cout<<"Exterieur " <<i << endl;
Exemples
Interieur 1
…
…
int j = 5;
cout<<"start \n ";
while(j == 0)
cout<<"j = "<<j--<<endl;
cout<<"end\n";
start
end
i=1;
while(i<5);{
cout<<"Interieur " <<i << endl;
i++;
}
itération
…
…
16
++- 31M. BENJELLOUN : 2019 UMONS
do while = REPETER … tant que
do
{ /* bloc d'instructions */
............;
............;
} while (Condition vraie);Condition
vraie
oui non
Bloc
d’instructions
programme
int j = 5;
do
cout<<"j = "<<j--<<endl;
while(j > 0);
cout <<"stop\n";
Suite du programme
(garantit l’exécution au moins une fois)
int j = 5;
do {
cout<<"j = "<<j <<endl;
j--;
} while(j > 0);
cout <<"stop\n";
j = 5
j = 4
j = 3
j = 2
j = 1
stop
++- 32M. BENJELLOUN : 2019 UMONS
#include …
void main() {
bool sortir = false;
char rep;
cout<<"Avant la boucle"<<endl;
while(!sortir) {
cout<<"Dans la boucle"<<endl;
cout<<"Voulez vous quitter (O/N)?"<<endl;
cin>>rep;
if(rep==‘O’ || rep == ‘o’)
sortir=true;
}
cout<<"Apres la boucle"<<endl;
}
#include …
void main() {
bool sortir = false;
char rep;
cout<<"Avant la boucle"<<endl;
do {
cout<<"Dans la boucle"<<endl;
cout<<"Voulez vous quitter (O/N)?"<<endl;
cin>>rep;
if(rep=='O’ || rep == ‘o’)
sortir=true;
} while(!sortir) ;
cout<<"Apres la boucle"<<endl;
}
Les itérations
17
++- 33M. BENJELLOUN : 2019 UMONS
Les itérations
for( init ; (Condition vraie); itération)
{
/* bloc d'instructions */
}
for (i = 0; i <4; i++) {
cout << "i = " << i << endl;
}
while (Condition vraie){
............; /* bloc d'instructions */
............;
............;
}
int i = 0;
while(i < 4) {
cout<< "i = " << i << endl;
i++;
}
do
{
............; /* bloc d'instructions */
............;
}
while (Condition vraie);
int i = 0;
do {
cout<< "i = " << i << endl;
i++;
} while(i < 4);
++- 34M. BENJELLOUN : 2019 UMONS
Début programme
Fin
instructions
cout << " Modifier n = " ;cin >> n ;
if ( n == x) {…
}else {
…}
for (x = 0; x < 7; x++) {cout << "x = " << x << endl;
}
while(x<7) {…
}
do {…
} while(x < 7);
#include <iostream>
using namespace std;
int main ()
{
return 1;
}
int n=2, x ; // commentaire
x=3;
instructions2
instructions1
If OK?O
If OK?
instructions
O
N
N
18
++- 35M. BENJELLOUN : 2019 UMONS
Pour rompre le déroulement séquentiel d'une suite d'instructions
Instructions d'échappement
return (expression);permet de sortir de la fonction qui la contient
exit (expression);La fonction est interrompue. ‘expression’ : un entier
indiquant le code de terminaison du processus
for (i = -10; i <= 10; i++) {
if (i == 0)
continue;// pour éviter la division par zéro
cout << 1 / i;
}
while (Condition vraie) {............ ;
............ ;
continue;............ ;
............ ;
break;............ ;
............ ;
}............ ;
#
8
int i;
for (i = -3; i <= 3; i++) {cout << i << endl ;if(i = = 0) {
break;cout << " break ";
}}cout << "Fin " ;
-3-2-10Fin
++- 36M. BENJELLOUN : 2019 UMONS
switch = AU CAS OU ... FAIRE ...
…
switch(variable de type char ou int) // au cas où la variable vaut:
{
case valeur1: ......; // variable=valeur1 : exécutez ce bloc d'instructions.
.......;
break;
case valeur2:........; // variable=valeur2: exécutez ce bloc d'instructions.
........;
break;
.
. // etc ...
.
default: .......; /* aucune des valeurs précédentes: exécutez ce bloc
........; d'instructions, pas de "break" ici.*/
}
Le bloc "default" n'est pas obligatoire. valeur1, valeur2, …. doivent être des expressions
constantes. L’instruction switch correspond à une cascade d’instructions if ...else
19
++- 37M. BENJELLOUN : 2019 UMONS
….
void main( ) {
const float PI= 3.14159;float rayon = 3.5;float diametre, circonference, surface;int choix;
cout << "1. Calculer la circonference\n";cout << "2. Calculer la surface\n";cout << "3. Calculer le diametre\n";cout << "Votre choix?";cin >> choix;
switch (choix) {case 1 : circonference = 2*PI*rayon; break;case 2 : surface = PI*rayon*rayon; break;case 3 : diametre = 2*rayon; break;default : cout << "Mauvais choix…\n";
}}
char choix;
switch(choix)
{
case '1': …
!switch(i) {
case 2 * j:
....
float f;
switch(f) {
case 2:
....
switch : instruction commode pour les "menus"
++- 38M. BENJELLOUN : 2019 UMONS
Tableaux et Strings
Un tableau est une collection de variables de même type, appelées éléments
Type Nom_Tableau[dim];
int tab[4]; déclare un tableau de 4 valeurs entières tab[0] tab[1] tab[2] tab[3]
const int SIZE = 5;
int A[SIZE] // A est un vecteur de 5 entiers
float B[5]
int A[SIZE] = { 10, 20, 30, 40, 50 };
int premier[] = { 1, 2, 3, 5, 7, 11, 13 };
char Tab_Char[4] = { 'A', 'C', 'F', 'G' };
int Tab[50] = { 0 };
int i = 10;
int a[i];
int primes[];
Déclaration
Initialisation
Interdiction
Constante
20
++- 39M. BENJELLOUN : 2019 UMONS
Accès aux éléments d’un tableau
Les éléments sont numérotés de 0 à dim-1
Il n’y a pas de vérification des bornes
void main( ) {
const int dim=6;
int i;
int A[dim] = { 1, 2, 3, 4, 5, 6 };
for (i=0;i<dim;i++) {
cout<<"A["<<i<<"]="<<A[i];
}
}
A[0]=1 A[1]=2 A[2]=3 A[3]=4 A[4]=5 A[5]=6
void main(){
int a[6];int i = 7;
a[0] = 9; a[5] = -10;a[i/2] = 2;
a[6] = 0;a[-1] = 5;
}
0
a
1
2
3
4
5
9
?
?
2
?
-10
Type Nom_Tableau[dim];
++- 40M. BENJELLOUN : 2019 UMONS
Chaînes de caractères ou String
char Nom[dim];Initialisation
Pour terminer la chaîne, on place en fin de chaîne le caractère nul '\0', de code ASCII 0.
Ce caractère est soit ajouté automatiquement par le compilateur, soit introduit par le programmeur, selon les fonctions utilisées.
char S[] = {'H','e','l','l','o','\0'}; 'H' 'e' 'l' 'l' 'o' '\0'
S[0] S[1] S[2] S[3] S[4] S[5] char S[6] = "Hello";
char S[5] = "Hello"; 'H' 'e' 'l' 'l' 'o'
char S[] = "Le main"; 'L' 'e' ' ' 'm' 'a' 'i' 'n' '\0'
• Un tableau de char à une dimension : char Nom[dim];
• Un type spécial string : string Nom; // Il faut inclure <string>
21
++- 41M. BENJELLOUN : 2019 UMONS
string Nom; // Il faut inclure <string>
string Nom est équivalente à string Nom = ""; . Donc par défaut la chaîne est vide.
Il existe de nombreuses façons d’initialiser Ident, par exemple :
string s1 = "Bonjour a vous";
string s2 = s1; // s2 contient " Bonjour a vous "
string s3(4, 'x'); // équivaut à string s3 = "xxxx"
string s4(s1, 4, 8); // s4 contient "our a vo“ S1 de 4 + 8
B o n j o u r a v o u s0 1 2 3 4 5 6 7 8 9 10 11 12 13
#include <string>…string ST = "Salut";char H[6] = "Hello";
for (int i=0; i<5; i++) cout << ST[i] << " "; // affichera : S a l u t
for (int i=0; i<5; i++) cout << H[i] << " "; // affichera : H e l l o
++- 42M. BENJELLOUN : 2019 UMONS
Pourquoi utiliser string Nom; plutôt que char Nom[dim]; ?
char S1[6] = "Salut", S2[6] = "Hello", S3[12];
S1= S2; S1= "Hooo"; S3=S1+S2; if(S1= =S2) … Interdit
string S1 = "Salut", S2 = "Hello", S3;
S1= S2; S1= "Hooo"; S3=S1+S2; if(S1= =S2) … Autorisé
S1= "Hello"
S1= "Hooo"
S3= "HoooHello"
false
22
++- 43M. BENJELLOUN : 2019 UMONS
#include <iostream>
#include <string> // traitement de string
using namespace std; // espace de nommage std pour importer les
// symboles de la bibliothèque standard C++
void main(void) {
string nom1, nom2, nom3 ;
int len, size;
cout << "Donnez Nom1 : " ; cin >> nom1;
cout << "Donnez Nom2 : " ; cin >> nom2;
len = nom1.length(); // nombre de caractères dans nom1
size = nom2.size(); // nombre de caractères dans nom2
cout << "Nom1 : "<<nom1 << " Dim Nom1 = " << len << endl;
cout << "Nom2 : "<<nom2 << " Dim Nom2 = " << size << endl;
nom3 = nom2+ " " +nom1;
cout << "Nom3 = "<< nom3 << endl;
if(nom1>nom2) cout << "nom1 > nom2" << endl;
else if (nom1==nom2) cout << "nom1 = nom2" << endl;
else cout << "nom1 < nom2" << endl;
nom1=nom2;
cout << "nom1 = " << nom1 << " nom2 : " << nom2 << endl;
}
Donnez Nom1 : salut
Donnez Nom2 : hello
Nom1 : salut Dim Nom1 = 5
Nom2 : hello Dim Nom2 = 5
Nom3 = hello salut
nom1 > nom2
nom1 = hello nom2 : hello
Donnez Nom1 : csou
Donnez Nom2 : pi
Nom1:csou Dim Nom1 = 4
Nom2:pi Dim Nom2 = 2
Nom3 = pi csou
nom1 < nom2
nom1 = pi nom2 : pi
++- 44M. BENJELLOUN : 2019 UMONS
Algorithmes de triNom de l’algorithme Complexité
Tri à bullesTri par sélectionTri par insertion
Tri de Shell (shell sort) : Amélioration du tri par insertion
Tri fusion (merge sort) : Tri rapide (quick sort) : Tri par tas (heap sort) :
O(N2)O(N2)O(N2)
O(N log2 N)
O(N log N)O(N log N)O(N log N)
23
++- 45M. BENJELLOUN : 2019 UMONS
Tri à bullesbubble sort
répéterpermutation = FALSE;commencer au début du drapeau;
Pour i variant de 0 à N – 2 faire si cellule [i] ">" cellule [i+1]alors
débutpermuter cellules;permutation = TRUE;fin
jusqu'à ce que (not permutation)
Complexité : O(N²) Proportionnel à N² permutations
void TriaBulles (int x[], int N) {int i, perm=1, tmp; while (perm==1) {
perm =0;for (i=0;i<N-1;i++) {
if(x[i] > x[i+1]) {tmp = x[i];x[i] = x[i+1];x[i+1] = tmp;perm = 1;
}}
}}
Algorithmes de tri
++- 46M. BENJELLOUN : 2019 UMONS
void tri_par_selection (int X[], int N) {int i, j, min, tmp;for (i = 0 ; i < N - 1 ; i++) {
min = i;for(j = i+1 ; j < N ; j++)
if(X[j] < X[min])min = j;
if(min != i) {tmp = X[i];X[i] = X[min];X[min] = tmp;
}}}
Le tri par sélection
consiste en la recherche du plus grand élément (le plus petit) que l'on va replacer en dernière position (en première), puis on recherche le second plus grand élément (le second plus petit) que l'on va replacer également à sa position finale et ainsi de suite.
Algorithmes de tri
24
++- 47M. BENJELLOUN : 2019 UMONS
Recherche d'un élément dans un tableau
Recherche linéaire
Recherche dichotomique (binary search)
0
9
1
3
2
6
3
2
4
1
5
12
6
0
Est une méthode efficace pour retrouver un élément dans un tableau trié.
A chaque étape de la recherche dichotomique, l’intervalle de recherche est divisé par deux.
On utilise dès lors deux index de recherche : la borne inférieure et la borne supérieure.
0
2
1
4
2
6
3
8
4
10
5
12
6
14
inf supmid
0
2
1
4
2
6
3
8
4
10
5
12
6
14
inf sup
On initialise les bornes inf et sup à la première et dernière valeur des index du tableau tab
respectivement
◼ Le milieu est donné par
mid = (inf+sup) / 2; (0+6)/2 =3
◼ Supposons que l’on recherche la valeur i=6. On
compare cette valeur avec tab[mid]=8. Comme
tab[mid]>i, on change mid en sup.
◼ mid = (inf+sup) / 2; (0+3)/2 =1
◼ inf=1 et sup=3
◼…
++- 48M. BENJELLOUN : 2019 UMONS
4.4. Écrire un programme qui supprime le premier et le dernier élément d’un vecteur.
vecteur initial : Tab → 0 1 2 3 4 5 6
sup. bords ➔ 1 2 3 4 5
sup. bords ➔ 2 3 4
4.5. Écrire un programme qui supprime le milieu du tableau et ajoute son double au début.
vecteur initial : Tab → 1 2 3 4 5
sup. Aj ➔ 6 1 2 4 5
sup. Aj ➔ 4 6 1 4 5
4.6. Codez un programme de tri à bulles d'un vecteur de strings.
4.7. Codez un programme de recherche dichotomique d'un nombre dans un vecteur de
strings rangés par ordre croissant.
25
++- 49M. BENJELLOUN : 2019 UMONS
MatricesRangées ligne par ligne
Considérées comme des vecteurs de lignes
Accès aux composantes par double crochets
int a[10][5];
a[1][0] = 7;
int x[2][2] = {{1,2},{3, 4}}; // 2 lignes et 2 colonnes
1 2
3 4 #include …
void main(){
int i, j, tab[5][4];
for (i = 0; i <5; i++) { // Saisie
for (j = 0; j < 4; j++) tab[i][j] = i;
}
for (i = 0; i <5; i++) { // Affichage
for (j = 0; j < 4; j++) cout<< tab[i][j] << ' ' ;
cout << endl;
}
}
0 0 0 0
1 1 1 1
2 2 2 2
3 3 3 3
4 4 4 4
++- 50M. BENJELLOUN : 2019 UMONS
Affichage de la table de multiplication
26
++- 51M. BENJELLOUN : 2019 UMONS
#include <iostream>using namespace std;
void main() {int i,j;int a[3][3], b[3][3], c[3][3];
cout<<" Entrer matrice1 "<<"\n";for(i=0;i<3;i++)
for(j=0;j<3;j++)cin>>a[i][j];
cout<<" Entrer matrice2 "<<"\n";for(i=0;i<3;i++)
for(j=0;j<3;j++)cin>>b[i][j];
cout<<" Solution : ";
for(i=0;i<3;i++) {cout<<"\n";for(j=0;j<3;j++) {
c[i][j]=a[i][j]-b[i][j];cout<<c[i][j]<<"\t";
}}}
Que fait ce programme ?
++- 52M. BENJELLOUN : 2019 UMONS
Fonctions en C++
• Encapsule un traitement particulier formant un tout
• Peut implémenter la notion de module en logique• Augmente la lisibilité d’un programme
• Réalise un objectif précis• Améliore le débogage et la maintenance d’un programme
Son utilisation se décompose en trois phases :
• Définition de la fonction
• Déclaration de la fonction
• Appel de la fonction
Définition d’une fonction
Fonctions pourquoi ?
Déclarer et appeler une fonction
Règles de visibilité des variables
Passage des paramètres par valeur et par adresse
Fonction renvoyant une valeur au programme
Passage des tableaux aux fonctions
Fonctions et récursivité
27
++- 53M. BENJELLOUN : 2019 UMONS
Type nom_fonction(liste_param_typés)
{
//déclaration de variables locales
…. /* Corps de la fonction */
….
return (valeur);
}
Définition d’une fonction
Une fonction renvoie une valeur ou rien
liste_param_typés = 0, void ou plusieurs
int Somme(int x, int y) {
int S; // Variable locale à Somme
S= x+y;
return S ;}
void fonction1()
{
cout<<"\n fonction1 \n";
void fonction2(){cout<<"\n fonction2 \n";}
}
L'imbrication de fonctions
n'est pas autorisée
Définition
++- 54M. BENJELLOUN : 2019 UMONS
…
void main(){
int i, j, SomCar1=0, SomCar2=0, SomCar3=0;
for (i = 0; i <5; i++) {
SomCar1 = SomCar1 + i*i ;
}
cout<<" SC="<<SomCar1<< endl;
for (i = 0; i <10; i++) {
SomCar2 = SomCar2 + i*i ;
}
cout<<" SC="<<SomCar2<< endl;
for (j = 0; j < 7; j++) {
SomCar3 = SomCar3 + j*j ;
}
cout<<" SC="<<SomCar3<<endl;
}
…
void Fnct_SomCar(int N){
int i, S=0;
for (i = 0; i <N; i++)
S = S + i*i ; //S+=i*i;
cout<<" SC="<<S<< endl;
}
void main(){
Fnct_SomCar(5) ;
Fnct_SomCar(10) ;
Fnct_SomCar(7) ;
}
Fonctions pourquoi ?
28
++- 55M. BENJELLOUN : 2019 UMONS
…
void main(){
Fnct_SomCar(5) ;
Fnct_SomCar(10) ;
Fnct_SomCar(7) ;
}
void Fnct_SomCar(int N){
int i, S=0;
for (i = 0; i <N; i++)
S = S + i*i ;
cout<<" SC="<<S<< endl;
}
5
Fonctions pourquoi ?10
++- 56M. BENJELLOUN : 2019 UMONS
Fonctions pourquoi ?
#include <iostream>
using namespace std;
void main(){
int i, j, SomCar1=0, SomCar2=0, SomCar3=0;
for (i = 0; i <5; i++) {
SomCar1 = SomCar1 + i*i ;
}
for (i = 0; i <10; i++) {
SomCar2 = SomCar2 + i*i ;
}
for (j = 0; j < 7; j++) {
SomCar3 = SomCar3 + j*j ;
}
cout<<" SC1="<<SomCar1<<" SC2="
<< SomCar2 <<" SC3="<<SomCar3;
}
#include <iostream>
using namespace std;
int Fnct_SomCar(int N){
int i, S=0;
for (i = 0; i <N; i++)
S = S + i*i ; //S+=i*i;
return S;
}
void main(){
int SomCar1, SomCar2, SomCar3;
SomCar1 = Fnct_SomCar(5) ;
SomCar2 = Fnct_SomCar(10) ;
SomCar3 = Fnct_SomCar(7) ;
cout<<" SC1="<<SomCar1<<" SC2="
<< SomCar2 <<" SC3="<<SomCar3;
}
29
++- 57M. BENJELLOUN : 2019 UMONS
…
void main(){
int Val1, Val3;
…
Val1 = Fnct1_() ;
Fnct2_() ;
Val3 = Fnct3_() ;
}
……….………..return entier;
int Fnct1_()
……….………..Fnct4_();………..………..
void Fnct2_()
……….………..………..………..
void Fnct4_()
……….………..return entier;
int Fnct3_()
Fonctions pourquoi ?
++- 58M. BENJELLOUN : 2019 UMONS
…
int Somme(int x, int y);
void main(void) {
int a=5; b=6, Som;
Som = Somme(7,7);
cout <<" Som = "<< Som<< endl;
cout <<" Som = "<< Somme(a,b);
}
int Somme(int x, int y) {
int S;
S= x+y;
return S ;
}
…
int Somme(int x, int y) {
int S;
S= x+y;
return S ;
}
void main(void) {
int a=5; b=6, Som;
Som = Somme(7,7);
cout <<" Som = "<< Som<< endl;
cout <<" Som = "<< Somme(a,b);
}
Déclaration et appel d’une fonction
30
++- 59M. BENJELLOUN : 2019 UMONS
void main(void){
int Val ;Val = addition();cout << "val = "<< Val<<endl;
}
int addition(){
float tmp;tmp = calcule(2.5,3) + calcule(5,7.2);return (int)tmp;
}
float calcule(float C, float D){
return ( (C + D ) / 2) ;}
float calcule(float, float);
int addition();
float calcule(float A, float B){
return ( (A + B ) / 2) ;}
int addition(){ // Appel d’une fonction dans une fonction
float tmp;tmp = calcule(2.5,3) + calcule(5,7.2);return (int)tmp;
}
void main(void){
int Val ;Val = addition();cout << "val = "<< Val<<endl;
}
Déclaration et appel d’une fonction
++- 60M. BENJELLOUN : 2019 UMONS
#include <iostream>
using namespace std;
void Modifier(int v);
void main(){
int v = 5; // Variable locale à main()
Modifier(v); // Appel de la fonction Modifier
cout << "\n Main: v = " << v; /* Affiche la valeur de v après
passage dans la fonction Modifier*/
}
void Modifier(int v){
v = v *100; // Modifie la copie
cout << "Modifier: v = "<< v; /* Affiche la valeur de v dans la
fonction Modifier*/
}
Modifier: v = 500
Main: v = 5
v= 5
V’ = 500
Les paramètres sont copiés. La fonction travaille donc sur une copie de v.
31
++- 61M. BENJELLOUN : 2019 UMONS
#include <iostream>
using namespace std;
void Addition(int v, float f);
void main(){
int v = 5;
float f= 4.5 ;
Addition(v, f); // Appel de la fonction
cout << "\n Main: v et f " << v << "et " <<f;
}
void Addition(int v, float f){
cout << " Addition: v + f = "<< v+f << endl;
f = f + v;
cout << " Addition: f = "<< f ;
}
Addition : v+f = 9.5
Addition : f = 9.5
Main: v et f = 5 et 4.5
v= 5 et f=4.5
5+ 4.5
f = 9.5
Les paramètres sont copiés. La fonction travaille donc sur une copie de v.
++- 62M. BENJELLOUN : 2019 UMONS
Fonction Renvoyant une valeur au programme
#include <iostream>
using namespace std;
int change(int X);
void main(void){
int var = 5;
int valeur;
valeur = return_Val (var);
cout <<"main: var = "<< var << endl;
cout <<"main: valeur = "<< valeur;
}
int return_Val (int v)
{
v = 100;
cout <<" return_Val : v = "<< v << endl;
return (v+1);
}
return_Val : v = 100main: var = 5main: valeur = 101
Une fonction se termine et ‘rend la main’ à
la fonction appelante lorsque son exécution
rencontre l’instruction: return expression;
ou return;
32
++- 63M. BENJELLOUN : 2019 UMONS
#include <iostream>
using namespace std;
int return_Val (int Z);
void main(void){
int var = 5, valeur;
valeur = return_Val(var);
cout << "main: var = " << var << endl;
cout << "main: valeur = "<< valeur;
}
int return_Val(int v)
{
if (v == 10) return (2*v);
else return (3*v);
}
#include <iostream>
using namespace std;
int return_Val (int K);
void main(void){
int var = 5;
int valeur;
valeur = return_Val(var);
cout << "main: var = " << var << endl;
cout << "main: valeur = "<< valeur;
}
int return_Val(int v) {
if (v == 10) return (2*v);
else return (3*v);
cout <<" return_Val v = "<< v<<endl;
}
Qu’affiche ce programme à l’écran ? Qu’affiche ce programme à l’écran ?
++- 64M. BENJELLOUN : 2019 UMONS
Fonctions et récursivité
Tours de HanoïSuite de Fibonacci
un = un-1 + un-2
u0=u1=1
Puissance entière
Une fonction est dite récursive lorsqu’elle s’appelle elle-même.
int factorielle (int n )
{
if ( n < 0) return (–1); //code d'erreur
else if ( n == 0 ) return 1; // 0! = 1
else
return n* factorielle( n-1 ); // n! = n*(n-1)!
}
a x an-1 si n > 0
1 si n = 0
an =
33
++- 65M. BENJELLOUN : 2019 UMONS
Passer des tableaux aux fonctions
Les tableaux peuvent être passés comme paramètres d'une fonction.
Ils ne peuvent pas être retournés comme résultat d'une fonction.
La longueur du tableau ne doit pas être définie à la déclaration de la fonction.
Un tableau peut être modifié dans une fonction. Il est passé par référence (adresse) et
non par valeur.
!
#include …
void Modif(int a[]){
a[0] = 5;
a[1] = 6;
}
void main(void){
int p[2] = { 1, 2 };
cout << p[0] << " ; " << p[1];
Modif(p);
cout << p[0] << " ; " << p[1];
}
1 ; 2
5 ; 6
#include …
void Modif(int x[], int n);
void main(void){
int i;
int p[6] = { 1, 2, 3, 5, 7, 11 };
Modif(p, 6);
for (i=0;i<6;i++)
cout<< p[i];
}
void Modif(int a[], int n){
int i;
for(i = 0; i <n ; i++)
a[i] = 5;
}
++- 66M. BENJELLOUN : 2019 UMONS
#include <iostream>
using namespace std;
const int Nmax=20;
int menu(); //Déclarations des fonctions
void saisie (int N, float T[ ]);
void affichage (int N, float T[ ]);
int main () //Programme principal
{ .....
float T[Nmax];
…..
case 1: saisie (N, T);
affichage (N, T);
break;
}
}
………..
return 1;
}
void saisie (int n, float A[ ]) {….}
void affichage (int n, float A[ ]) {….}
…
void saisie (int N, float T [ ])
{
cout<<"Entrez les données du tableau "<<endl;for(int i=0;i<N;i++) {
cout<<"entrez la valeur "<<i+1<<endl;cin>> T[i];
}
}
void affichage (int N, float T [ ])
{
cout<< " Les valeurs sont : " <<endl;for(int i=0;i<N;i++) {
cout<<" T["<<i+1<< " ] = "<< T[i]<<endl;}
}
34
++- 67M. BENJELLOUN : 2019 UMONS
Écrire un programme modulaire qui permet de saisir et afficher les éléments de deux
tableaux (Tab1[10] et Tab2[10]) contenant des noms. Le nombre d’éléments (N1 et
N2) saisis peut être différents pour chacun des deux tableaux mais ne peut dépasser
10 éléments.
Combien de fonctions Saisie et Affiche? Justifiez.
++- 68M. BENJELLOUN : 2019 UMONS
#include …
int LaSomme( ) {
int A[Nmax], N;int S = 0;
for (int i=0;i< N ;i++) {
cout <<"Entrez A["<<i<<"]=";
cin >>A[i];
S= S+ A[i];
}
return S;
}
void main() {
const int Nmax = 7;
int i, A[Nmax], S=0, N=3;
S = LaSomme( );
cout << " Affichage :" << endl;
Affichage(A, N);
cout << "\n La somme est = "<< S ;
}
Qu’affiche ce programme à l’écran ?
void Affichage( int A[], int N) {
for (int i=0;i < N ;i++) {
cout << " A["<<i<<"]= "
<<A[i] <<endl;
}
}
35
++- 69M. BENJELLOUN : 2019 UMONS
#include …
void Saisie_T( int tab[] ) {
int N, i;
N= 3;
for (i = 0; i <N; i++) tab[i] = i;
}
void Affiche_T(int tab[], int N ) {
int i;
for (i = 0; i <N; i++) cout << tab[i];
}
void main(){
int T[20], n;
Saisie_T( T );
Affiche_T(T, n );
}
tab[0] = 0
tab[1] = 1
tab[2] = 2
Qu’affiche ce programme à l’écran ?
++- 70M. BENJELLOUN : 2019 UMONS
void Saisie_Mat( int tab[][4], int m, int n) {
int i, j;
for (i = 0; i <m; i++)
for (j = 0; j < n; j++)
tab[i][j] = i;
}
0 0 0 0
1 1 1 1
2 2 2 2
3 3 3 3
Matrice Exemple
void Affiche_Mat( int tab[][4], int m, int n)
{
for (int i = 0; i <m; i++) {
for (int j = 0; j < n; j++)
cout << tab[i][j] << " ";
cout << endl;
}
}
#include <iostream>
using namespace std;
void main(){
int T[5][5];
Saisie_Mat( T , 4, 4 );
Affiche_Mat( T , 4, 4 );
}
36
++- 71M. BENJELLOUN : 2019 UMONS
#include …
int return_Val(int , int);
void main(void){
int var1 = 5, var2=0;
int valeur;
valeur = return_Val(var1, var2);
cout << "var1 = " << var1
<< " var2 = "<<var2 << endl;
cout << "main: valeur = "<< valeur;
}
int return_Val(int v1, int v2) {
v1 = 10;
v2 = 7;
return …;
}
Comment retourner v1 et v2?
++- 72M. BENJELLOUN : 2019 UMONS
#include <iostream> …
void affiche (int a, int b) {
cout<<" a = " << a << endl << " b = " << b ;
}
void echange(int x,int y){
int tmp;
tmp = x;
x = y;
y =tmp;
}
void main() {
int a = 1 , b = 5;
cout << "Avant " <<endl;
affiche(a,b);
echange(a,b);
cout << "\nAprès " <<endl;
affiche(a,b);
}
Avant
a = 1
b = 5
Après
PASSAGE DES PARAMETRES
Transmission des arguments
Comment échanger a et b ?
a = 1 b = 5
PAR VALEUR
37
++- 73M. BENJELLOUN : 2019 UMONS
Le pointeur prend comme
valeurs des adresses de
données en mémoire
' '
Types de base …. donnée
8
donnée
35….
Adr i Adr j
Mémoire
12FF80 12FF84
L'adresse de l'élément i est &i → i=8 et &i= 12FF80
int i=8, j=35;
Et les pointeurs ?
…. p=12FF84 …. 35 ….
12FF8412FF80
int *p; *p est le contenu pointé par p→ 35
p est l’adresse → 12FF84
++- 74M. BENJELLOUN : 2019 UMONS
Déclaration de PointeursLe symbole * est utilisé entre le type et le nom du pointeur
Déclaration d’un entier: int i;int *p;Déclaration d’un pointeur vers un entier:
Exemples de déclarations de pointeurs
int *pi; // pi est un pointeur vers un int ; *pi désigne le contenu de l'adresse
float *pf; // pf est un pointeur vers un float
char c, d, *pc; // c et d sont des char; pc est un pointeur vers un char
int C = 4;
int *p;
p = &C; // p reçoit l'adresse de c; donc pointe sur c.
cout << "*p = "<<*p<<endl;
cout << "p = "<<p <<endl;
cout <<" *(&C) "<<*(&C);
*p = 4
p = 0x12FF7C
*(&C) = 4
L'adresse de C est &C
38
++- 75M. BENJELLOUN : 2019 UMONS
' '
Une référence vers un objet permet de définir un nouveau nom, un alias, pourdésigner l’emplacement mémoire de l’objet référencé. En tant qu'alias, laréférence doit impérativement être initialisée, avec l'objet référencé.
int i = 35, j;
int &ref = i ; /* ref une référence sur la variable i. permet au programme de manipuler i
sous un autre nom que celui sous lequel elle a été déclarée.
i et ref deux identificateurs qui représentent la même variable */
int &ErRef; // INTERDIT : une référence doit être initialisée
j = ref; // j = la valeur de l'objet référencé par ref→ (j = i = 35)
ref = 100 ; // ref=i= 100 ; j reste à 35
i = j ; // ref=i=j = 35
Les Références en C++
++- 76M. BENJELLOUN : 2019 UMONS
#include …
void Modifier(int v);
void main(){
int v = 5;
Modifier(v);
cout << "\nmain: v = " << v;
}
void Modifier(int v){
v = v *100;
cout << "Modifier: v = "<< v;
}
#include …
void Modifier(int *v);
void main(){
int v = 5;
Modifier(&v);
cout << "\nmain: v = " << v;
}
void Modifier(int *v){
*v = *v *100;
cout << "Modifier: *v = "<< *v;
}
#include …
void Modifier(int &v);
void main(){
int v = 5;
Modifier(v);
cout << "\nmain: v = " << v;
}
void Modifier(int &v){
v = v *100;
cout << "Modifier: v = "<< v;
}
par Valeur Pointeur Référence
Appel par valeurs, pointeurs, références ??!!
var = 5
var = 500
Modifier: v = 500
main: v = 5
Modifier: *v = 500
main: v = 500
Modifier: v = 500
main: v = 500
var = 5
var = 500
39
++- 77M. BENJELLOUN : 2019 UMONS
#include …
void fonct (int a)
{
a=1 ;
}
void main(void){
int var = 5;
fonct (var);
cout << var << endl;
}
5
#include …
int fonct (int a)
{
a=1 ;
return a;
}
void main(void){
int var = 5;
var = fonct (var);
cout << var << endl;
}
1 1
#include …
void fonct (int *a)
{
*a=1 ;
}
void main(void){
int var = 5;
fonct (&var);
cout << var << endl;
}
#include …
void fonct (int &a)
{
a=1 ;
}
void main(void){
int var = 5;
fonct (var);
cout << var << endl;
}
1
++- 78M. BENJELLOUN : 2019 UMONS
#include <iostream> …
void affiche (int a, int b) {
cout<<"\t i = " << a << " j = " << b << endl;
}
void echange (int, int);
void main () {
int i= 1, j=5;
affiche (i, j);
echange (i, j);
affiche (i, j);
}
void echange (int a, int b)
{
int tmp;
tmp = b;
b = a;
a = tmp;
}
void echange (int*, int*);
void main () {
int i= 1, j=5;
affiche (i, j);
echange (&i, &j);
affiche (i, j);
}
void echange (int *a, int *b)
{
int tmp;
tmp = *b;
*b = *a;
*a = tmp;
}
void echange (int&, int&);
void main () {
int i= 1, j=5;
affiche (i, j);
echange (i, j);
affiche (i, j);
}
void echange (int &a, int &b)
{
int tmp;
tmp = b;
b = a;
a = tmp;
}
i = 1 j = 5
i = 1 j = 5
i = 1 j = 5
i = 5 j = 1
i = 1 j = 5
i = 5 j = 1
40
++- 79M. BENJELLOUN : 2019 UMONS
#include <iostream> …
int return_Val(int , int);
void main(void){
int var1 = 5, var2=0;
int valeur;
valeur = return_Val(var1, var2);
cout << "var1 = " << var1
<< " var2 = "<<var2 << endl;
cout << "main: valeur = "<< valeur;
}
int return_Val(int v1, int v2) {
v1 *= 10;
v2 += 7;
return …;
}
Comment retourner v1 et v2?
#include <iostream> …
void return_Val(int &, int&);
void main(void){
int var1 = 5, var2=0;
int valeur;
valeur = return_Val(var1, var2);
cout << "var1 = " << var1
<< " var2 = "<<var2 << endl;
cout << "main: valeur = "<< valeur;
}
void return_Val(int &v1, int &v2) {
v1 *= 10;
v2 += 7;
return …;
}
var1 = 50 var2 = 7
++- 80M. BENJELLOUN : 2019 UMONS
#include <iostream> …
void somme(int , int , int &);
int modif(int , int &, int &);
void main(){
int a, b, c;
a = 2; b = 8;
somme(a, b, c);
cout <<"Somme de a="<<a<<" et b="<<b<<" : " << c << endl;
a = modif(a, b, c);
cout << "Modif : a="<<a<<" et b="<<b<<" : " << c << endl;
}
void somme(int x, int y, int &z){
z = x + y;
y = 29;
}
int modif(int x, int &y, int &z){
x *= 2; y= x+ y; z= 5;
return x;
}
Somme de a= et b= :
Modif : a= et b= :
Qu'affiche le code à l'écran ?
41
++- 81M. BENJELLOUN : 2019 UMONS
Si x=1
Si x =2
Si x=3
Si x=4
Si x=5
…
int Fonct1(int y){
y = 10; return (y);
}
void Fonct2(int y){
y = 11; exit(0);
}
void Fonct3(int y){
y = 12;
}
void Fonct4(int &y){
y = 13;
}
void main() {
int x=0, y=0;
cin >> x;
if (x== 1) y = Fonct1(y);
if (x== 2) Fonct2(y);
if (x== 3) return ( );
if (x== 4) Fonct4(y);
if (x== 5) Fonct3(y);
cout <<"ICI y="<<y ;
}
++- 82M. BENJELLOUN : 2019 UMONS
Allocation dynamique de la mémoire
int *p; new int
p = new int ;
T= new int[N];
0 1 2 3 4 5 6
Tableaux réserver plus de places en mémoire que nécessaire.
42
++- 83M. BENJELLOUN : 2019 UMONS
Allocation dynamique de la mémoire
Tableaux réserver plus de places en mémoire que nécessaire.
Création d’un tableau
de taille quelconque→
l'allocation dynamique
#include <iostream> …
void affiche(int T[], int d, char C[]){
for(int i=0; i<d; i++)
cout<< "\n T["<<i<<"] = " << T[i] << " C["<<i<<"] = " <<C[i];
cout << endl;
}
void main(){
int N, *T, i;
cout << " N = " ; cin >> N;
char *C = new char[N];
T= new int[N]; affiche(T, N, C);
for(i=0; i<N; i++){
T[i]=i;
C[i]='A'+i;
}
affiche(T, N, C);
delete[] T; affiche(T, N, C);
delete[] C; affiche(T, N, C);
}
T[0] = -842150451 C[0] = ◙
T[1] = -842150451 C[1] = ◙
T[2] = -842150451 C[2] = ◙
T[0] = 0 C[0] = A
T[1] = 1 C[1] = B
T[2] = 2 C[2] = C
T[0] = -572662307 C[0] = A
T[1] = -572662307 C[1] = B
T[2] = -572662307 C[2] = C
T[0] = -572662307 C[0] = ¦
T[1] = -572662307 C[1] = ¦
T[2] = -572662307 C[2] = ¦
++- 84M. BENJELLOUN : 2019 UMONS
Tableau de taille quelconque
#include <…
void saisie_vect(int Tab[], int n) {
for(int i=0;i<n;i++)
cin >> Tab[i];
}
void Affiche(int Tab[], int dim) {
for(int i=0;i<dim;i++)
cout << "Tab[" << i <<"]="
<< i <<Tab[i];
}
void main() {int *tab, n;
cout << " N= ";
cin >> n;
tab = new int [n];
saisie_vect(tab, n);
Affiche(tab, n);
delete [] tab;
}
#include <…
void main() {
int **T; // pointeur sur un pointeur sur un entier
int i, j, lignes, colonnes;
cout << "\nEntrez le nb de lignes et de colonnes: ";
cin >> lignes >> colonnes;
T = new int* [lignes]; // Alloc. d’un tableau de pointeurs
// pour chaque ligne, alloc. du nb de col.
for (i=0; i<lignes; i++)
T[i] = new int[colonnes];
for (i=0; i<lignes; i++)
for (j=0; j<colonnes; j++) {
cout <<"T[" <<i <<"," <<j <<"]: ";
cin >> T[i][j];
}
//...// Destruction
for (i=lignes-1; i>=0; i--)
delete[] T[i];
delete[] T;
}
Tableau dynamique à deux dimensions
43
++- 85M. BENJELLOUN : 2019 UMONS
#include <iostream>
using namespace std;
void affiche(int a, int b) {
cout << "Deux entiers:" << a << "et" << b << '\n';
}
void affiche(float a, float b) {
cout << "Deux reels:" << a << "et" << b << endl;
}
void affiche(int c) {
cout << "Un entier:" << c << '\n';
}
void main() {
affiche (5.2 , 6.3);
affiche (1 , 2);
affiche (100);
}
Surcharge des fonctions
Le C++ permet d’utiliser des fonctions qui portent le même nom mais pas
le même type et/ou le nombre de paramètres.
++- 86M. BENJELLOUN : 2019 UMONS
Paramètres par défaut
#include <iostream>
using namespace std;
void affiche(int un = 1, int deux = 2, int trois = 3) {
cout << un << ' ' << deux << ' ' << trois << '\n';
}
void main(void) {
affiche(1, 2, 3);
affiche(5, 6, 7);
affiche(100, 200);
affiche(1000);
affiche();
}
1 2 35 6 7100 200 31000 2 31 2 3
44
++- 87M. BENJELLOUN : 2019 UMONS
Règles de visibilité des variables
Le C++ est un langage structuré en blocs { } , les variables ne peuvent être utilisées
que là où elles sont déclarées.
#include <iostream>using namespace std;
void main() {int i = 10;
for (int i = 0; i <3 ; i++) { cout << i << endl;
}
cout << i << endl;}
++- 88M. BENJELLOUN : 2019 UMONS
Règles de visibilité des variables
#include <iostream>
using namespace std;
void main() {
const float PI= 3.14159;
float rayon = 3.5;
float circonference, surface;
int choix;
cout << "1. Calculer la circonference\n";
cout << "2. Calculer la surface\n";
cout << "Votre choix?";
cin >> choix;
switch (choix) {
case 1 : rayon = 0;
circonference = 2*PI*rayon;
cout << circonference << endl; break;
case 2 : surface = PI*rayon*rayon;
cout << surface << endl; break;
}
}
Le C++ est un langage structuré en blocs { } , les variables ne peuvent être utilisées
que là où elles sont déclarées.
45
++- 89M. BENJELLOUN : 2019 UMONS
Règles de visibilité des variables
#include …
int globale=0;
void fonc(int v) {double d, f; i++;globale --;
}
void main(void) {int i = 5, j; float f = 2.8, g;d = 3.7;globale =10;cout << " valeur de j= " << j ; cout << "\nglobale = " << globale ;fonc (i);cout << "\nglobale = " << globale ;
}
(0)
(1)
(2)
(3)
(4)
(5)
#include …
int g;
void affichage(int un, int deux) {
cout << un << " " << deux << " " << g << endl;
}
void fonct(int un, int deux){
affichage(un, deux);
un += 2; deux += 2; g += 2;
affichage(un, deux);
}
void main(void) {
int i = 5, j;
affichage(i, j);
j=10;
fonct(i, j);
affichage(i, j);
}
5 -858993460 0
5 10 0
7 12 2
5 10 2
++- 90M. BENJELLOUN : 2019 UMONS
#include <iostream>
using namespace std ;
int k=0;
void Fct1(){
k++;
cout << "\nFct1: k = "<< k;
}
void Fct2(){
k++;
cout << "\nFct2: k = "<< k;
}
void main(){
cout << "main: k = " << k;
Fct1();
Fct2();
Fct1();
Fct2();
cout << "\nmain: k = " << k;
}
#include <iostream>
using namespace std ;
int k=0;
void Fct1(){
k++; cout << "\nFct1: k = "<< k;
}
void Fct2(){
int I=30;
k++;
cout << "\nFct2: k = "<< k;
I++;
cout << "\n\n Fct2: I = "<< I;
}
void main(){
cout << "main: k = " << k;
Fct1();
Fct2();
Fct1();
Fct2();
cout << "\nmain: k = " << k;
}
Règles de visibilité des variables
46
++- 91M. BENJELLOUN : 2019 UMONS
#include <iostream>
using namespace std ;
int k=0;
void Fct1(){
k++; cout << "\nFct1: k = "<< k;
}
void Fct2(){
static int I=30;
k++;
cout << "\nFct2: k = "<< k;
I++;
cout << "\n\n Fct2: I = "<< I;
}
void main(){
cout << "main: k = " << k;
Fct1();
Fct2();
Fct1();
Fct2();
cout << "\nmain: k = " << k;
}
#include <iostream>
using namespace std ;
int k=0;
void Fct1(){
k++; cout << "\nFct1: k = "<< k;
}
void Fct2(){
int I=30;
k++;
cout << "\nFct2: k = "<< k;
I++;
cout << "\n\n Fct2: I = "<< I;
}
void main(){
cout << "main: k = " << k;
Fct1();
Fct2();
Fct1();
Fct2();
cout << "\nmain: k = " << k;
}
Règles de visibilité
++- 92M. BENJELLOUN : 2019 UMONS
#include …
const int Nmax=20;
void main() {
int i,N=3,tab[Nmax];
saisie(tab,N);
for(i=0;i<N;i++)
cout <<tab[i];
}
void saisie(int tab[], int N) {
int i;
for(i=0;i<N;i++)
cin>>tab[i];
N=15;
}
mon_programme.cppMémoire utilisée par mon_programme.cpp
Nmax=20 i N=3
Mémoire pour saisie()
i N=3N=15
Tab[Nmax] 5 -1 9
i=0i=1i=2
i=0i=1i=2
i=3
…
47
++- 93M. BENJELLOUN : 2019 UMONS
Gestion des fichiers en C++
Pour manipuler un fichier en C++ il faut #include <fstream>
On y trouve essentiellement les classes:• ofstream (output file stream) permet d’écrire les données dans le fichier ;• ifstream (input file stream) permet de lire les données du fichier ;
Ouverture et fermeture d’un fichier :
ofstream output, X;output.open("Res.txt"); ou output.open("c:\\labojeudi\\Res.txt");X.open("Data"); ou X.open("A:\\Data");
Écriture :
Lecture : ifstream input ;input.open("Data.txt"); ou input.open("c:\\labojeudi\\Data.txt");
++- 94M. BENJELLOUN : 2019 UMONS
#include <fstream> …
void main() {
ofstream Ecri;
char Tab1[6]="Hello";
int Tab2[5]={1,2,3,4,5};
Ecri.open("Mon_fichier.txt");
Ecri << "Mes Donnees" << endl;
for(int i=0; i<5; i++){
Ecri << Tab1[i] << " "
<< Tab2[i]<<endl;
}
Ecri.close();
}
Mes Donnees
H 1
e 2
l 3
l 4
o 5
#include <fstream> …
void main() {
ifstream Lec;
char Tab1[6], Titre[100];
int Tab2[5], i=0;
Lec.open("Mon_fichier.txt");
Lec.getline(Titre,100); cout << Titre << endl;
while(!Lec.eof()){
Lec >> Tab1[i] >> Tab2[i];
cout << Tab1[i] << " ; " << Tab2[i]<< endl;
i++;
}
Lec.close();
}
Mes Donnees
H ; 1
e ; 2
l ; 3
l ; 4
o ; 5
o ; 5??
Test!
Mon_fichier.txt
48
++- 95M. BENJELLOUN : 2019 UMONS
Ecri.open("Mon_fichier.txt");
if(Ecri) { // if (Ecri!= NULL)
// on vérifie si l'ouverture se passe bien
Ecri << "Mes Donnees" << endl;
for(int i=0; i<5; i++){
Ecri << Tab1[i] << " "
<< Tab2[i]<<endl;
}
Ecri.close();
}
else { // si échec à l'ouverture
cout<<"Erreur"<<endl;
}
if (Ecri.bad()) return 0;
Ecri.fail()
++- 96M. BENJELLOUN : 2019 UMONS
Les Structures
Structure = ensemble de variables définissant un nouveau type sousun seul nom.
Les structures sont définies en utilisant le mot-clé struct.
struct Date {int jour;int mois;int an;
};
Déclarer des instances
struct Date paques, semaine[7];
Date noël; // pas de struct
Date nouvel_an = { 1, 1, 2019 }; // Initialisation
49
++- 97M. BENJELLOUN : 2019 UMONS
Structure dans Structurestruct Date
{
int jour;
int mois;
int an;
};
struct Etudiant {char nom[30];string prenom;char *adresse;int numero;float Cotes[3];struct Date D_Nais;
};
Etudiant J_D = {
"Dupont", "Jpp",
"rue de Houdain, 9, 7000 Mons",
102,
10.5, 11, 14.5,
{ 15, 10, 2000 }
};
Les membres sont accédés par le nom de
l’instance, suivi de . , suivi du nom du membre
cout <<"nom = "<< J_D.nom;
cout <<"\n Cote 0 = "<< J_D.Cotes[0]<< endl;
cout << " jour de naissance "<<J_D. D_Nais.jour;
++- 98M. BENJELLOUN : 2019 UMONS
Student191000
Obé
Lix
191001
Astér
Ix
100009
Tint
In
101899
Tourne
Sol
struct Student {int Id;char nom[30];string prenom;
};
struct Student Tab[Nmax];
50
++- 99M. BENJELLOUN : 2019 UMONS
#include …
struct Article{
string nom;
int prix;
};
int main( ) {
Article T[5];
for (int i=0; i<5; i++)
{
cout << "Entrez le nom : ";
cin >> T[i].nom;
cout << "\nEntrez le prix ";
cin >> T[i].prix;
}
return 1;
}
nom1
150
nom2
13
nom3
439
nom4
99
Nom5
31
T[0] T[1] T[2] T[3] T[4]
++- 100M. BENJELLOUN : 2019 UMONS
#include …
struct Article{
string nom;
int prix;
};
void Affiche(Article AR){
cout << "\n\t Nom = " << AR.nom << " Prix = " << AR.prix;
}
void main(void) {
Article A, T[5];
cout << "Entrez le nom : "; cin >> A.nom;
cout << " \nEntrez le prix "; cin >> A.prix;
Affiche(A);
for (int i=0; i<5; i++){
cout << "Entrez le nom : "; cin >> T[i].nom;
cout << "\nEntrez le prix "; cin >> T[i].prix;
Affiche(T[i]);
}
}
nom1
prix1
nom2
prix2
nom3
prix3
nom4
prix4
…
T[0] T[1] T[2]
Et si nom contenait un espace ?Exp. Mon Smartphone
51
++- 101M. BENJELLOUN : 2019 UMONS
#include …
struct Article{
string nom;
int prix;
};
void Affiche(Article AR){
cout << "\n\t Nom = " << AR.nom
<< " Prix = " << AR.prix;
}
void Saisie(Article AR){
cout << "Entrez le nom : "; cin >> AR.nom;
cout << "\nEntrez le prix :"; cin >> AR.prix;
}
void main(void) {
Article A;
Saisie(A);
Affiche(A);
}Entrez le nom :
Entrez le prix :
? Une structure peut être passée, comme une autre variable, par valeur ou par adresse ?
???
++- 102M. BENJELLOUN : 2019 UMONS
#include …
struct Article{
string nom;
int prix;
};
void Saisie(Article &AR){
cout << "Entrez le nom : "; cin >> AR.nom;
cout << "\nEntrez le prix :"; cin >> AR.prix;
}
void main( ) {
Article T[5];
for (int i=0; i<5; i++)
Saisie(T[i]);
}
T[i]=Nouv();
Article Nouv(){
Article AA;
cout << "Entrez le nom : "; cin >> AA.nom;
cout << "\nEntrez le prix :"; cin >> AA.prix;
return AA;
}
L’opération d’affectation = peut se faire
avec des structures
52
++- 103M. BENJELLOUN : 2019 UMONS
struct E{
int x;
int y ;
} ;
#include …
void fonct (E *a) {
*a.x=1 ; *a.y=2;
}
void main(void){
struct E V;
V.x=V.y=0;fonct (&V);
cout << V.x << V.y;}
1 2
#include …
void fonct (E a) {
a.x=1 ; a.y=2;
}
void main(void){
struct E V;
V.x=V.y=0;
fonct (V);
cout << V.x << V.y;
}
0 0
#include …
E fonct (E a) {
a.x=1 ; a.y=2;
return a;
}
void main(void) {
struct E V;
V.x=V.y=0;
V = fonct (V);
cout << V.x << V.y;}
1 2
#include …
void fonct (E &a) {
a.x=1 ; a.y=2;
}
void main(void){
struct E V;
V.x=V.y=0;fonct (V);
cout << V.x << V.y;}
1 2
++- 104M. BENJELLOUN : 2019 UMONS
Passer des tableaux aux fonctions
#include …
void Modif(int a[]){
a[0] = 5;
a[1] = 6;
}
void main() {
int p[2] = { 1, 2 };
cout <<p[0] <<" ; "<<p[1];
Modif(p);
cout <<p[0] <<" ; "<<p[1];
}
1 ; 2
5 ; 6
#include …
void Modif(struct E a[]){
a[0].x = a[0].y = 5;
a[1].x = a[1].y = 6;
}
void main( ) {
struct E p[2];
p[0].x= p[0].y= p[1].x= p[1].y = 0 ;
Modif(p);
cout << p[0].x << " ; "<< p[0].y;
cout << p[1].x << " ; "<< p[1].y;
}
53
++- 105M. BENJELLOUN : 2019 UMONS
struct Elem{
int x ;
string y ;
} ;
3
Nom1
2
Nom4
5
Nom5
…
…
Elem Tab[Cste];
void Saisie(Elem Tab[], int n) {
for(int i=0; i<n; i++) {
cout << "\n le nom de l article: "
cin >> Tab[i].y;cout << "\n le prix de l article: ";
cin >> Tab[i].x;}
}
Manipulation d’un tableau
++- 106M. BENJELLOUN : 2019 UMONS
void Saisie(struct article Tab[], int &N)
{ …
N?? // tester
for(int i=0;i<N;i++) {
cout << "\n \n entrer le nom de l article: ";
cin >> Tab[i].Nom;
cout << "\n entrer le Code de l article: ";
cin >> Tab[i].Code;
cout << "\n entrer le prix de l article: ";
cin >> Tab[i].Prix;
}
…
1- Saisie et affichage:
Est constitué de deux fonctions :
Saisie (…...) ; // de type void
Dans cette fonction, on demandera et on testera N < Nmax pour initialiser
le tableau (par exemple 5) et on effectuera la saisie.
Affichage (…….) ;
struct article {string Nom;char Code;float Prix;
};
Manipulation d’un tableau
54
++- 107M. BENJELLOUN : 2019 UMONS
struct article {string Nom;char Code;float Prix;
};
void main() {
struct article Tab[Nmax];
…
do{
rep_menu=menu();
switch(rep_menu) {
case 1: Saisie(Tab,n);
Affichage(Tab, n);
break;
default : cout << " Il faut choisir entre 1) .... et 8) \n";
}
}while (rep_menu!=8);
. . . . . .
++- 108M. BENJELLOUN : 2019 UMONS
const int NMax = 5;
struct Etudiant{
string nom ;
int numero ;
int Matieres[NMax] ;
} ;
void saisie(Etudiant T[], int n, int NM) {
…
n?
NM?
…
}
const int NMax = 5;
struct Etudiant{
char *nom ;
int numero ;
int Matieres[NMax] ;
} ;
8.2. et 8.3. Écrire le même programme que 8.1. en remplaçant la structure par :
8.4 Donnez la structure représentant ce tableau :
Nom adresse Sexe res1 res2
… resN Code Myne
nom1 56 rue je ne sais pas, bte 10, …
M 10 15 … 8 A 13.3
nom2 33, rue qui n’existe pas, …
F 10 20 … 19 V 15.7
nom3 … M 13 14 … 15 C 13.9
nom20 … F 10 10 … 11 D 10.2
Écrire un programme permettant de manipuler un
tableau de cette structure. Ce programme doit gérer
en boucle le menu suivant :
1 - SAISIE et AFFICHAGE du tableau
2 - Sauvegarde dans un fichier
3 - Lecture fichier
4 - ARRET du programme
55
++- 109M. BENJELLOUN : 2019 UMONS
☺☺☺
Les listes sont des structures de données dynamiques, linéaires. Elles sont composées de cellules chaînées les unes aux autres par pointeurs.
NULL
NULL
Une cellule étant une structure qui contient un élément à stocker et un pointeur sur la prochaine cellule de la liste.
struct Cellule{int Data;struct Cellule *suiv; // pointeur sur le prochain maillon
};
++- 110M. BENJELLOUN : 2019 UMONS
Modéliser une liste chaînée consiste à allouer dynamiquement les cellules
chaque fois que cela est nécessaire.
TêteElm1 Elm2 Elm3 Elm4
Liste simplement chaînée
@4000 Elem1
@ 0700
Elem2
@ 0900
Elem3
@ 2170
Elem4
NULL
@4000 @0700 @0900 @2170
Tête_List
Liste simplement chaînée
56
++- 111M. BENJELLOUN : 2019 UMONS
Allouer et assigner une Cellule
Cette fonction réserve l'espace mémoire nécessaire pour une nouvelle Cellule
dans la liste, assigne les données, et retourne un pointeur sur cette Cellule.
struct CEL{
string name;
struct CEL * suiv;
};
CEL cel, *Pcel;
cel . name = "Toto";
Pcel →name = "Jo";
Toto
NULL
debut
Nouvelle cellule dans une liste chaînée vide
CEL *debut;
debut = new CEL;
debut→name = "Toto";
debut→suiv = NULL;
Le début de la liste est indiqué par un pointeur indépendant (debut) et la fin par NULL
Liste simplement chaînée
++- 112M. BENJELLOUN : 2019 UMONS
NULL
CEL *prec;
prec = new CEL;
prec→name= “Jo";
prec→suiv = debut;
debut = prec; prec
Jo Toto
debut
Ajouter une nouvelle cellule en tête de liste
Insérer une nouvelle cellule après la cellule prec
Claire Denis
NULL
prec
Jo Toto
NULL
prec
Alfred
p
debut
CEL *p;
p = new CEL;
p→name = "Alfred";
p→suiv = prec→suiv;
prec→suiv = p;
Liste simplement chaînée
57
++- 113M. BENJELLOUN : 2019 UMONS
Recherche dans une liste
boolean EstDansL(string x, CEL a) {while (a != null) {if (a.name == x) return true;a = a.suiv;
}return false;
}
struct CEL{string name;struct CEL * suiv;
};
boolean EstDansL(string x, CEL a){for ( ; a != null; a = a.suiv)
if (a.name == x) return true;
return false;}
boolean EstDansL(string x, CEL a) {if (a == null)
return false;if (a.name == x)
return true;return EstDansL (x, a.suiv);}
Liste simplement chaînée
++- 114M. BENJELLOUN : 2019 UMONS
Une pile est une liste qui respecte la règle “dernier arrivé, premier sorti”, (Last In, First Out). C’est une structure de données pour laquelle l’ajout et la suppression d’un élément ne sont autorisés qu’à une seule extrémité, appelée sommet de la pile.
PILE [stack, LIFO]
Une file d'attente est une structure de données pour laquelle l’ajout et la suppression d’un élément ne sont autorisés qu’aux seules extrémités, appelées la tête et la queue de la file. Les éléments sont ajoutés en queue de file et sont retirés en tête de file. Premier entré/ Premier sorti → liste FIFO (First In, First Out).
FILE D'ATTENTE , queue [queue, FiFo]
Liste simplement chaînée
58
++- 115M. BENJELLOUN : 2019 UMONS
debut
Noeud?
debut
NULL
struct Noeud {int data;Noeud *next;Noeud *prev;
};
Liste chaînée
++- 116M. BENJELLOUN : 2019 UMONS
debut fin
NULL
debut→prev = NULL;
debut→next = fin;
fin→prev = debut;
NULL
fin→next = NULL;
data prev next
struct Noeud {int data;Noeud *next;Noeud *prev;
};
Liste doublement chaînée
59
++- 117M. BENJELLOUN : 2019 UMONS
Insérer un élément devant act
tmp->prev = act->prev ;
act->prev->next = tmp;
tmp->next = act;
act
data prev next
1
2
3
4
NULL
1
2
3
4
act->prev = tmp;
Liste doublement chaînée
++- 118M. BENJELLOUN : 2019 UMONS
Liste doublement chaînée
Liste dont les éléments ont un élément suivant et un élément précédent.Il n’y a pas de tête de liste, ni de fin de liste, la chaîne est fermée.
A B Cliste
Une liste avec un seul élément
Aliste
Liste doublement chaînée
60
++- 119M. BENJELLOUN : 2019 UMONS
a
b
c
d
e
f
g
La recherche d'un côté est plus lente que l'autre.
Arbres binaires
a
b
c
d
e
f
g
arbre équilibré
La différence entre la hauteur du sous-arbre gauche et la hauteur du sous-arbre droit est d'au plus une unité.
h
Un arbre binaire est un triplet (élément, sous_arbre, sous_arbre)
Arbres
struct cellule {int data;struct noeud *fils_gauche;struct noeud *fils_droit;
} ;
++- 120M. BENJELLOUN : 2019 UMONS
Arbre binaire de recherche ABR
Un arbre binaire de recherche est un arbre binaire tel que pour tout nœud X , les nœuds de son sous-arbre gauche s’ils en existent ont des valeurs inférieures ou égales à celle de X, et les nœuds de son sous-arbre droit des valeurs strictement supérieures.
X
<=X >X
Ce que l’on traduit par g(A) racine(A) < d(A).
Utilisation importante en Info pour la localisation, +, -, tri …
24
10 37
Arbres
Parcours d'un arbre binaire de recherche
Le parcours d’un arbre binaire consiste à examiner systématiquement dans un certain ordre tous les nœuds de l’arbre pour effectuer un traitement de données (ex. Affichage). Les parcours en profondeur : infixe, suffixe et préfixe se définissent de manière récursive et se distinguent par l'ordre dans lequel sont faits ces traitements.
61
++- 121M. BENJELLOUN : 2019 UMONS
I III
II
SI ABR
Le parcours infixe affiche les
éléments dans l’ordre croissant.
12
23
78
9
-77
2210-2
8
Parcours infixe (in-order)
infixe : -77, -2, 8, 9, 10, 12, 22, 23, 78
void infixe(arbre racine) {
if (! vide(racine)) {
infixe(racine→fils_gauche);
cout << racine→data;
infixe(racine→fils_droit);
}
}
Infixe(Fils_G)
Lister Père
Infixe (Fils_autres)
++- 122M. BENJELLOUN : 2019 UMONS
III
III
Postfixe :
-77, 8, -2, 10, 9, 22, 78, 23, 12
12
23
78
9
-77
2210-2
8 void Postfixe(arbre racine) {
if (! vide(racine)) {
Postfixe(racine→fils_gauche);
Postfixe(racine→fils_droit);
cout << racine→data;
}
}
Parcours Postfixe (suffixe ou post-order)
62
++- 123M. BENJELLOUN : 2019 UMONS
Préfixe :
12, 9, -2, -77, 8, 10, 23, 22, 78
12
23
78
9
-77
2210-2
8
Le parcours en profondeur à gauche consiste à partir de la racine et à tourner autour de l’arbre en allant toujours le plus à gauche possible. Le parcours se termine lorsqu’on est revenu à la racine par le côté droit.
void Prefixe(arbre racine) {
if (! vide(racine)) {
cout << racine→data;
Prefixe(racine→fils_gauche);
Prefixe(racine→fils_droit);
}
}
Lister Père
Prefixe(Fils_G)
Prefixe(Fils_autres)
Parcours Préfixe (pre-order)
Arbres
++- 124M. BENJELLOUN : 2019 UMONS
4
92
10631
875
Arbre non binaire
Principe: Parcours de gauche à droite:sur la position courante: l’enfant le plus àgauche a la priorité puis la position courante puis les autres enfants.
Infixe
10
93
8 721
654
Principe: On opère d’abord sur les feuilles (gauche) puis sur les branches.
Postfixe
1
52
10643
987
Principe: Depuis la racine, descendre la hiérarchiequand on arrive sur une feuille, on remonte jusqu’ à une branche non visitée auparavant.
Préfixe
Exemple: Parcours
Arbres
63
++- 125M. BENJELLOUN : 2019 UMONS
Exemples3
18
0 29
Parcours infixe :Infixe(Fils_G)
Lister Père
Infixe(Fils_autres)
Posfixe(Fils_G)
Posfixe(Fils_autres)
Lister Père
4Parcours préfixe :
Lister Père
Prefixe(Fils_G)
Prefixe(Fils_autres)
Arbres
1
2 3 4
5 6 7
Parcours postfixe :
Qu’est-ce que les parcours préfixe, infixe et postfixe affichent pour ces 3 arbres?
+
* ./.
+2 a
a
b
1
+*2a./.b+a1
++- 126M. BENJELLOUN : 2019 UMONS
rechercher : valeur x dans arbre == Rech(x,arbre) → booléen
On compare l’élément à la valeur de la racine :
- si le sous-arbre sélectionné est vide, l’élément est absent → échec
rechercher ( x , ) = faux
- si égalité → succès x = r ➔ rechercher (x ,<r , g , d > ) = vraie
Recherche d’un élément Recherche dichotomique
- si la valeur est plus petite, on recommence récursivement dans le sous-arbre
gauche ; et réciproquement si la valeur est plus grande dans le sous-arbre droit
x < r ➔ rechercher (x , < r , g , d > ) = rechercher (x , g )
x > r ➔ rechercher (x , < r , g , d > ) = rechercher (x , d )
Complexité : Dans le pire des cas, la complexité est en O ( hauteur de l’arbre < N).
Arbres
64
++- 127M. BENJELLOUN : 2019 UMONS
La structure de tas est un arbre vérifiant les deux propriétés suivantes:• L’arbre est un arbre binaire parfait• La valeur de tout nœud est >= à celle de ses descendants
La structure de tas
24
23
7
16
1
22108
5 4 20
24
23
7
16
1
22208
5 4 10
tant que ( y racine ) et ( y > père(y) ) faireéchanger y et père(y)
Arbres
++- 128M. BENJELLOUN : 2019 UMONS
Tri par tas [Heap sort]Principe : deux phases
- Construire un tas contenant les n éléments par adjonction successives ; en O (n log n).
- Tant que le tas n’est pas vide, répéter l'opération de prendre l'élément de la racine (max), le retirer du tas avec réorganisation, mettre ce max à sa place définitive ; en O (n log n).
15
14 5
8 13 2 3
3
14 5
8 13 2 15
réorganisation
Suppression
14
13 5
8 3 2 15
Arbres