0% ont trouvé ce document utile (0 vote)
175 vues95 pages

Introduction au Langage C++ et Concepts Clés

Transféré par

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

Introduction au Langage C++ et Concepts Clés

Transféré par

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

Chapitre 3

Généralités sur le langage C++.

A. SERGHINI 1
1- Présentation du langage C++

 Le langage C++ a été conçu à partir de 1982 par Bjarne


Stroustrup ingénieur au laboratoire Bell.

 L’objectif principal de B. Stroustrup était d’ajouter des


classes au langage C et donc, en quelque sorte, de
. greffer sur un langage de programmation procédurale
classique des possibilités de programmation orienté
objet (en abrégé P.O.O).

 Dés 1982, C++ a connu plusieurs versions, jusqu’à sa


normalisation par l’ANSI (American National Standards
Institute) en 1998.

A. SERGHINI 2
2- Étapes permettant l’édition, la mise au point,
l’exécution d’un programme en C++

1- Édition du programme source, à l'aide d'un éditeur


(traitement de textes). Le nom du fichier contient
l'extension .CPP, exemple: EXI_1.CPP.
.
2- Compilation du programme source, c'est à dire création
des codes machine destinés au microprocesseur utilisé.
- Le compilateur indique les erreurs de syntaxe mais ignore
les fonctions-bibliothèque appelées par le programme.
- Le compilateur génère un fichier binaire, non éditable en
mode « texte », appelé fichier objet: EXI_1.OBJ
(commande « compile »).

A. SERGHINI 3
3- Éditions de liens: Le code machine des fonctions-
bibliothèque est chargé, création d'un fichier binaire, non
éditable en mode texte, appelé fichier exécutable:
EXI_1.EXE.

4- Exécution du programme (commande « Run » ).

A. SERGHINI 4
Exemple :

A. SERGHINI 5
3- Espaces de noms C++

 Lorsque plusieurs bibliothèques sont utilisées, deux


fonctions différentes peuvent avoir le même nom sans
faire la même tâche. Pour éviter ce problème, le C++
définit les espaces de noms :
. namespace MaBiblio{
fonc1() ;
fonc2() ;
...}

 Un espace de nom à un comportement similaire à un


répertoire pour les systèmes d’exploitations.

 Ce qui est défini dans un espace de noms n’existe pas


en dehors.

A. SERGHINI 6
 Pour utiliser une fonction définie dans un chemin
d’accès il faut utiliser le chemin d’accès :
int main(){
fon1() // erreur fonc1() n’existe pas
MaBiblio::fonc2() // ok
...}
 Pour éviter d’alourdir le code, il est possible de préciser
que les membres d’un espace de noms seront utilisés
directement grâce aux mot clef using.
 Il y a deux méthodes :

1- Accéder à tout l’espace de noms

using namespace MaBiblio


fonc1() // ok
fonc2() // ok

A. SERGHINI 7
2- Préciser les fonctions à utiliser

using Mabiblio::fonc1( )
fonc1() // ok
fonc2() // fonc2 n’existe pas en dehors
// de l’espace de nom

 La plupart des fonctions et classes de la librairie


standard du C++ sont déclarées dans un espace de nom.
 L’espace de nom std contient la grande majorité des
fonctions de la librairie standard.
 Habituellement, il est nécessaire d’utiliser « using
namespace std » au début de chaque programme C++
qui utilise cette librairie. Certains compilateurs
permettent de ne pas le faire.

A. SERGHINI 8
4- La gestion de la mémoire
La mémoire de l’ordinateur se comporte de trois zones
d allocation :

1- La pile:
 La pile contient les variables qui sont déclarées à
. l’intérieur des fonctions ou à des blocs ({…})
 Ces variables sont appelées variables locales ou
automatiques
 Elles sont créés à l’appel de la fonction et détruites à la
sortie de la fonction (respectivement à l’entrée et à la
sortie du bloc)
 Leurs durées de vie est donc la durés de vie de la fonction.

A. SERGHINI 9
2- La zone statique:
 La zone d’allocation statique contient les variables qui sont
déclarées en dehors de toutes fonction ou à l’intérieur
d’une fonction mais avec le qualifiant static.
 Ces variables sont appelées variables globales ou statiques
 Elles sont créés à l’exécution du programme et détruites à
. la fin de celui-ci
 Leurs durées de vie est donc la vie du programme.
3- Le tas:
 Le tas contient les variables qui sont créés par le
programme au cours de son exécution. On parle
d’allocation dynamique.
 Ces variables sont appelées variables dynamiques
 Leurs durées de vie est donc variable.

A. SERGHINI 10
5- Types prédéfinis

5-1 Les différents types de variables :

 Une variable est une abstraction d’une portion de


mémoire
.  Une variable est caractérisée par :
(Nom, adresse, valeur, type, durée de vie, portée)
 L’emplacement de la déclaration décide de sa portée.
 Son adresse est déterminée pendant l’exécution et sa
valeur dépend des instructions dans lesquelles elle
apparaît.

A. SERGHINI 11
 Le C++, est un langage typé, chaque entité doit disposer d’un type.

Void : type vide ( pas de type )


Bool : type logique (true/false) (C++ )
Char : caractères
int : entiers
float : réels
double : réels en double précision
Tableaux
Pointeurs
wchar_t : caractères longs (C++)

A. SERGHINI 12
5-2 Types –Tailles :

1- Les entiers

Le langage C++ distingue plusieurs types d'entiers:


___________________________________________________________
TYPE DESCRIPTION TAILLE MEMOIRE
___________________________________________________________
int entier standard signé 4 octets: - 2^31 ≤ n ≤ 2^31-1
unsigned int entier positif 4 octets: 0 ≤ n ≤ 2^32
short entier court signé 2 octets: - 2^15 ≤ n ≤ 2^15-1
unsigned short entier court non signé 2 octets: 0 ≤ n ≤ 2^16
char caractère signé 1 octet : - 2^7 ≤ n ≤ 2^7-1
unsigned char caractère non signé 1 octet : 0 ≤n ≤ 2^8
_____________________________________________________________

A. SERGHINI 13
Numération:

- Endécimal les nombres s'écrivent tels que,


- En hexadécimal ils sont précédés de 0x.
exemple: 127 en décimal s'écrit 0x7f en hexadécimal.
Remarque:
En langage C++, le type char possède une fonction de
changement de type vers un entier:
- Un caractère peut voir son type automatiquement
transformé vers un entier de 8 bits
- Il est interprété comme un caractère alphanumérique du
clavier.

A. SERGHINI 14
2- 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:
_______________________________________________
TYPE DESCRIPTION TAILLE MEMOIRE
_________________________________________________________
Float réel standard 4 octets
double réel double précision 8 octets
__________________________________________________________

A. SERGHINI 15
5-3 Les initialisations :

 Le langage C++ permet l'initialisation des variables dès


leurs déclarations:
char c; est équivalent à char c = 'A';
c = 'A';
int i; est équivalent à int i = 50;
i = 50;

 Cette règle s'applique à tous les nombres, char, int, float ...
Pour améliorer la lisibilité des programmes et leur efficacité,
il est conseillé de l’utiliser.

A. SERGHINI 16
5-4 La portée d'une variable
C++ permet de déclarer des variables n’importe où et de les
initialiser dans un bloc. La porté d’une variable dépend de
l’endroit ou il est placé:
 Globale: Les variables globales sont déclarées en dehors de toute
fonction Elle est allouée et initialisée automatiquement avant
l'entrée dans la fonction 'main'.
Elle est nettoyée et libérée automatiquement après la sortie de la
fonction 'main'.
 Locale: (dite également automatique) est visible dans le bloc
d’instructions dans lequel elle à été déclaré et ce, à partir de sa
déclaration. Elle est allouée et initialisée.
Elle est nettoyée et libérée automatiquement, lorsqu’on sort du
block d’instructions
Dynamique: est totalement contrôlée par le programmeur.

A. SERGHINI 17
5-5 Classe de stockage :
Le C/C++ dispose des classes de stockage qui permettent de
spécifier la portée de la variable :

• auto : la
classe de stockage par défaut. Les variables ont pour portée
le bloc d’instructions où sont définis. Leur durée de vie est restreinte
à ce bloc.

• static : permet
de créer des variables dont la portée est le bloc
d’instructions en cours, mais qui, contrairement aux variables auto,
ne sont pas détruites lors de la sortie de ce bloc. À chaque fois que
l’on rentre dans ce bloc d’instructions, les variables statiques
existeront et auront pour valeurs celles qu’elles avaient avant que l’on
quitte ce bloc.

• const : la
variable désigne en fait une constante ; aucune
modification n’est autorisée dans le programme.
A. SERGHINI 18
• extern : est
utilisée pour signaler que la variable peut être définie
dans un autre fichier.

• register : onpeut demander qu’une variable de type entier,


caractère ou pointeur soit implantée dans un registre, ce qui est
souvent utile quand on veut aller vite.
Attention : seule une variable automatique peut être de type
registre. De plus, le mot-clé register, ne donne qu’une indication
au compilateur; on ne garantit pas que la variable sera bien en
registre, le compilateur n’ayant à sa disposition qu’un nombre
limité de registres.

• volatile : un
objet déclaré volatile peut être modifié par un
événement extérieur à ce qui est contrôlé par le compilateur
(exemple : variable mise à jour par l’horloge système).

A. SERGHINI 19
6- Les Flots cout et cin

 Un flot peut être considéré comme un « canal » :


- recevant de l’information : flot de sortie ;
- fournissant de l’information : flot d’entrée.
 Un flot peut être connecté à un périphérique ou un fichier.
. Par convention, le flot prédéfini cout est connecté à ce que
l’on nomme la « sortie standard ». De même, le flot prédéfini
cin est connecté à ce que l’on nomme « entrée standard ».
 On peut dire qu’un flot est un objet d’une classe prédéfinie,
à savoir ;
 ostream pour un flot de sortie ;
 istream pour un flot d’entrée.
.

A. SERGHINI 20
Exemple 1:

A. SERGHINI 21
Exemple 2:

A. SERGHINI 22
Exemple 3:

A. SERGHINI 23
7- Les opérateurs
 Opérateurs arithmétiques sur les réels:
+ - * / avec la hiérarchie habituelle.
 Opérateurs arithmétiques sur les entiers:
+ - * / (quotient de la division) % (reste de la division).
 Opérateurs relationnels
> >= <= < comparaisons
. == != égalité et inégalité
! négation (opérateur unaire)
&& ET relationnel
|| OU relationnel
 Opérateurs logiques sur les entiers:
& ET
| OU
^ OU EXCLUSIF
~ COMPLEMENT A UN
« DECALAGE A GAUCHE
» DECALAGE A DROITE.
.
A. SERGHINI 24
- Incrémentation- Décrémentation
Le langage C++ autorise des écritures simplifiées pour
l'incrémentation et la décrémentation de variables de type
entier (int, char, long)

i = i+1; est équivalent à i++;


i = i-1; est équivalent à i--;

- Opérateurs combinés
Le langage C++ autorise des écritures simplifiées lorsqu'une
même variable est utilisée de chaque côté du signe = d'une
affectation.
a = a+b; est équivalent à a+= b;
a = a-b; est équivalent à a-= b;
a = a & b; est équivalent à a&= b;

A. SERGHINI 25
8- Les déclarations des constantes
Le langage C++ autorise 2 méthodes pour définir des constantes.
1ere méthode:
déclaration d'une variable, dont la valeur sera constante pour
toute la portée de la fonction main.
Exemple :
.

 Dans ce cas, le compilateur réserve de la place en mémoire


(ici 4 octets), pour la variable pi, on ne peut changer la valeur.
 On peut associer «const » à tous les types.

A. SERGHINI 26
2 ème méthode:
Définition d'un symbole à l'aide de la directive de compilation
#define.
Exemple:

Le compilateur ne réserve pas de place en mémoire, on définit


ainsi une equivalence « lexicale ».
Souvent, les constantes déclarées par #define s'écrivent en
majuscules, mais ce n'est pas une obligation.

A. SERGHINI 27
Exercice 1:
Saisir un caractère au clavier, afficher son code ASCII à
l'écran.

Exercice 2:
Dans une élection, I est le nombre d’inscrits, V le nombre
de votants, P = 100V/I le pourcentage de votants, M = V/2
le nombre de voix pour obtenir la majorité.
Écrire un programme qui demande à l’utilisateur de saisir I
et V, puis calcule et affiche P et M.

Exercice 3:
Saisir 3 entiers, calculer et afficher leur moyenne.

A. SERGHINI 28
Chapitre 4
Les tests et les boucles en C++

[Link] 1
1- L‘instruction Si ... Alors ... Sinon ...

Syntaxe en C++:
if (condition)
{
............; // bloc 1 d'instructions
............;
. ............;
}
else
{
............; // bloc 2 d'instructions
............;
............;
}
suite du programme ...

[Link] 2
2- L'instruction Répéter ... Tant que ...

Syntaxe en C++:
do
{
............; // bloc d'instructions
. ............;
............;
}
while (condition);
suite du programme ...

 Le test se faisant après, le bloc est exécuté au moins


une fois.

[Link] 3
3- La boucle Tant que ... faire ...

Syntaxe en C++:
while (condition)
{
............; // bloc d'instructions
. ............;
............;
}
suite du programme ...

 Le test se fait d'abord, le bloc d'instructions n'est pas


forcément exécuté.

[Link] 4
4- L'instruction Pour ...

Syntaxe en C++:
for(instruction1; condition; instruction2)
{
. ............; // bloc d'instructions
............;
............;
}
suite du programme ...

[Link] 5
5- L'instruction Au cas ou ... Faire ...
 L'instruction switch permet des choix multiples uniquement sur des
entiers (int) ou des caractères (char).
Syntaxe C++:
switch(variable de type char ou int) au cas où la variable vaut:
{
case valeur1: ......; - cette valeur1: exécuter ce bloc d'instructions.
.......;
. break; - se brancher à la fin du bloc case.
case valeur2: ........; - cette valeur2: exécuter ce bloc d'instructions.
........;
break; - se brancher à la fin du bloc case.
.
. etc ...
.
default: .......; - aucune des valeurs précédentes: exécuter ce bloc
........; d'instructions, pas de "break" ici.
}
 le bloc "default" n'est pas obligatoire.
 L’instruction switch correspond à une cascade d’instructions if ...else

[Link] 6
Exercice-1:
L'utilisateur saisit un caractère, le programme teste s'il
s'agit d'une lettre majuscule, si oui il renvoie cette lettre
en minuscule, sinon il renvoie un message d'erreur.
Exercice-2:
Dans une élection, I est le nombre d’inscrits, V le nombre
. de votants, Q le nombre minimum de votants pour que le
vote soit déclaré valable, P = 100V/I le pourcentage de
votants, M = V/2 + 1 le nombre de voix pour obtenir la
majorité absolue. Écrire un programme qui
1- demande à l’utilisateur de saisir I, Q et V,
2- teste si le nombre minimum de votants pour que le vote
soit déclaré valable est atteint,
3- si oui calcule et affiche P, M, sinon affiche un message
d’avertissement.

[Link] 7
Exercice-3:
Écrire un programme permettant de saisir un entier n,
de calculer n!, puis de l’afficher. Utiliser une boucle do
...while puis while puis for.
Quelle est la plus grande valeur possible de n, si n est
déclaré int, puis unsigned int?
Exercice-4:
La formule récurrente ci-dessous permet de calculer la
racine du nombre 2 :
U0 = 1
Ui = ( Ui-1+ 2/Ui-1 ) / 2
Écrire un programme qui saisit le nombre d’itérations,
puis calcule et affiche la racine de 2.
Exercice-5:
Résoudre ax2 + bx +c = 0.

[Link] 8
Chapitre 5
Pointeur, Tableau, Allocation dynamique.

A. SERGHINI
Cours C++ 1
1- Les Pointeurs

Définitions
 Un pointeur p est une variable qui sert à contenir l’adresse
mémoire d’une autre variable.
 Si la variable v occupe plus d’une case mémoire, l’adresse
. contenue dans le pointeur p est celle de la première case
utilisée par v.
 La variable v est appelée variable pointée.
 Si p contient l’adresse de v alors on dit que p pointe sur v.
 Le pointeur possède un type qui dépend du type des
variables pointées.
 Un pointeur peut contenir aussi l’adresse d’une fonction,
on parlera alors de pointeur de fonctions.

A. SERGHINI
Cours C++ 2
Déclaration des pointeurs:
Une variable de type pointeur se déclare à l'aide du type de
l'objet pointé précédé du symbole *.

Exemple:
char *pc; pc est un pointeur sur un objet de type char
. int *pi; pi est un pointeur sur un objet de type int
float *pr; pr est un pointeur sur un objet de type float

 En dehors de la partie déclarative, l'opérateur * désigne en


fait le contenu de la case mémoire pointée.

 L’adresse d’une variable peut être obtenue grâce à


l’opérateur & suivi du nom de la variable.

A. SERGHINI
Cours C++ 3
Arithmétique des pointeurs
 On peut essentiellement déplacer un pointeur dans un plan
mémoire à l'aide des opérateurs d'addition, de
soustraction, d'incrémentation, de décrémentation.
 On ne peut le déplacer que d'un nombre de cases mémoire
multiple du nombre de cases réservées en mémoire pour la
variable sur laquelle il pointe.

Affectation d’une adresse à un pointeur


 Lorsque l'on déclare une variable char, int, float .... un
nombre de cases mémoire bien défini est réservé pour cette
variable. En ce qui concerne les pointeurs, l’allocation de la
case mémoire pointée obéit à des règles particulières :

A. SERGHINI
Cours C++ 4
Exemple:
char *pc;
- Si on se contente de cette déclaration, le pointeur pointe «
n’importe où ». Son usage, tel que, dans un programme
peut conduire à un « plantage » du programme ou du
système d’exploitation si les mécanismes de protection ne
sont pas assez robustes.
- L’initialisation du pointeur n’ayant pas été faite, on risque
d’utiliser des adresses non autorisées ou de modifier
d’autres variables.
Exemple d’affectation :
int i=5;
int * pi;
pi=&i;
cout <<"valeur de i = " << i<< endl;
cout <<"adresse de i = " << &i<< endl;
cout <<"adresse oŭ il pointe pi = " << pi<< endl;
A. SERGHINI
Cours C++ 5
Incompatibilité de types :
On ne peut pas affecter à un pointeur de typeT1 l’adresse
d ’une variable d ’autre type T2
Exemple:
int i=5;
char * pc; erreur
. pc=&i;
On peut cependant forcer la conversion.
A utiliser avec précaution ....

int i=5;
char * pc;
pc= ( char *) &i;

A. SERGHINI
Cours C++ 6
Pointeur Void :
 Les pointeurs void sont un type particulier de pointeur
 Ils peuvent pointer sur une variable de n’importe quel type
 On ne peut pas utiliser l’opérateur d’indirection * sur un
pointeur void. Il faut d’abord le convertir en un pointeur
d’un type donné.
Exemples :
int a=5, b=6;
int * pi=&a;
void * pv = &b; //correct
pv=pi //correct
pi =pv // !!! Erreur!!!
pi=(int*) pv //correct
cout <<*pv ; // !!! Erreur!!!
cout <<*((int *) pv ); //correct
A. SERGHINI
Cours C++ 7
2- Les Tableaux
 Les tableaux correspondent aux vecteurs et matrices en
mathématiques. Un tableau est caractérisé par sa taille et
par le type de ses éléments.

Les tableaux à une dimension:


. Déclaration: type nom[dim];
Exemples:
int compteur[10];
float nombre[20];
Cette déclaration signifie que le compilateur réserve dim
places en mémoire pour ranger les éléments du tableau.

Remarque:
dim est nécessairement une EXPRESSION CONSTANTE.
A. SERGHINI
Cours C++ 8
Les tableaux à plusieurs dimensions:
- Tableaux à deux dimensions:
Déclaration:
type nom[dim1][dim2];
Exemples:
int compteur[4][5];
. float nombre[2][10];

Initialisation des tableaux:


On peut initialiser les tableaux au moment de leur déclaration:
Exemples:
int liste[10] = {1,2,4,8,16,32,64,128,256,528};
float nombre[4] = {2.67,5.98,-8.0,0.09};
int x[2][3] = {{1,5,7},{8,4,3}}; // 2 lignes et 3 colonnes

A. SERGHINI
Cours C++ 9
Les Tableaux et Les Pointeurs

 Les identificateurs de tableaux et de pointeurs sont


similaires
 L’identificateur d’un pointeur désigne l’adresse de la
première case mémoire de la variable pointée
.  De même, l’identificateur d’un tableau désigne l’adresse de
la première case mémoire du tableau
 Il existe cependant une différence majeure:
- La valeur du pointeur peut être modifiée
- L’adresse du tableau ne peut pas être modifiée
 L’identificateur d’un tableau peut être considéré comme un
pointeur constant

A. SERGHINI
Cours C++ 10
Exemple:
const int MAX=7;
int tab[MAX]; int *p;
p=tab;
*p=0; //tab[0]=0
p++;
*p=10; //tab[1]=10
p=&tab[2];
*p=20; //tab[2]=20
. p=tab+3;
*p=30; //tab[3]=30
p=tab;
*(p+4)=40; //tab[4]=40
tab[5]=50; //tab[5]=50
*(tab+6)=60; //tab[6]=60
for ( int n=0; n<MAX; n++) cout << tab[n]<< " " ;
Résultats d’exécution:
0 10 20 30 40 50 60
 L’instruction telle que tab=p aurait provoqué une erreur à la
compilation
A. SERGHINI
Cours C++ 11
Exercice 1:
Un programme contient la déclaration suivante:
int tab[10] = {4,12,53,19,11,60,24,12,89,19};
Compléter ce programme de sorte d'afficher les adresses des
éléments du tableau.
Exercice 2:
Un programme contient la déclaration suivante:
int tab[20] = {4,-2,-23,4,34,-67,8,9,-10,11, 4,12,-53,19,11,-60, 24, 12,
89,19};
Compléter ce programme de sorte d'afficher les éléments du
tableau avec la présentation suivante:
4 -2 -23 4 34
-67 8 9 -10 11
4 12 -53 19 11
-60 24 12 89 19

A. SERGHINI
Cours C++ 12
3- L’ allocation dynamique
Intérêt de l’allocation dynamique
 L’allocation dynamique permet une gestion plus flexible de la mémoire
 Un programme n’utilise la mémoire dont il a besoins qu’au moment du
besoin
 Ainsi il évite de monopoliser de l’espace mémoire aux instants où il n’en a
pas besoins et permet donc à d’autres programmes de l’utiliser
 La mémoire peut ainsi être partagée de manières plus efficaces entre
plusieurs programmes.
.  - Supposant qu’un programme ait besoin d’afficher 100 objets graphiques
différents et que ces objets sont très volumineux (en espace mémoire).
- Supposant aussi qu’un instant donné, le programme n’a besoin d’afficher
simultanément et au maximum 10 objets parmi 100.
- Supposant que la taille de la mémoire permet au maximum le stockage
simultané de 30 objets graphiques
- Allouer les 100 objets de façon statique est impossible puisque l’espace
mémoire est insuffisant.
- En revanche, déclarer dynamiquement 10 objets est tout à fait possible et
le programme pourra alors s’exécuter sans problème pour 100 objets à des
instants différentes.
A. SERGHINI
Cours C++ 13
L’Opérateur new
 L’opérateur new permet l’allocation de l’espace mémoire
nécessaire pour stocker un élément d’un type T donné.
 Pour que l’opérateur new puisse connaître la taille de
l’espace à allouer il faut donc lui indiquer le type T
 Si l’allocation réussit (il y a suffisamment d’espace en
. mémoire) alors l’opérateur new retourne l’adresse de
l’espace alloué.
 Cette adresse doit être alors affectée à un pointeur de type
T pour pouvoir utiliser cet espace par la suite
 Si l’allocation échoue (il n’y a pas suffisamment d’espace
mémoire) alors l’opérateur new retourne NULL (0)

T *p;
P = new T ou T *p = new T
A. SERGHINI
Cours C++ 14
 Il est possible d’indiquer après le type T une valeur pour
initialiser l’espace ainsi alloué. Cette valeur doit être indiquer
entre parenthèses : new T (val)

Allocation d’un entier :


. //Sans initialisation //Avec initialisation
int *p = new int; int *p = new int (10);
*p =5; cout <<*p; // la valeur affichée 10
cout <<*p; // la valeur affichée 5

 On n’a pas vérifié ici si l’allocation a réussi. Dans la pratique,


il faudra le faire systématiquement.

A. SERGHINI
Cours C++ 15
 Pour allouer dynamiquement un tableau d’éléments il suffit
d’utiliser l’opérateur new [] en indiquant entre les crochets le
nombre d’éléments
 Contrairement aux tableaux statiques où le nombre
d’éléments devait être une constante (valeur connue à la
. compilation) ici le nombre d’éléments peut être variable dont
la valeur ne sera connue qu’a l’exécution (la valeur saisie par
l’utilisateur, lue à partir d’un fichier)
 On récupère alors du premier élément du tableau
T *p = new T[n]; // p contiendra l’adresse du premier élément

 Il n’est pas possible ici d’indiquer les valeurs d’initialisation

A. SERGHINI
Cours C++ 16
L’Opérateur delete

 Pour que l’allocation dynamique soit utile et efficace, il est


impératif de libérer l’espace réservé avec new dès que le
programme n’en a plus besoin.
.  Cet espace pourrait alors être réutilisé soit par le programme
lui-même soit par d’autre programmes
 Libération d’un élément simple : opérateur delete

int *p = new int;


*p =5;
cout<< *p<<endl;
delete p;

A. SERGHINI
Cours C++ 17
 Libération d’un tableau : opérateur delete []
int *p ,i,n;
cout<<“Nombre delements ?: “;
cin>> n;
. p= new int [n];
for (i=0;i<n;i++)
cin >>p[i];
for (i=0;i<n;i++)
cout<< p[i]*p[i]<<endl;
delete [] p;

A. SERGHINI
Cours C++ 18
Tableaux dynamiques à 2 dimensions:

• Un tableau à deux dimensions est, par définition, un


tableau de tableaux. Il s'agit donc en fait d'un pointeur vers
un pointeur. Considérons le tableau à deux dimensions
défini par :
int tab[M][N];

• tab est un pointeur, qui pointe vers un objet lui-même de


type pointeur d'entier. tab a une valeur constante égale à
l'adresse du premier élément du tableau, &tab[0][0].
• De même tab[i], pour i entre 0 et M-1, est un pointeur
constant vers un objet de type entier, qui est le premier
élément de la ligne d'indice i. l’élément tab[i] a donc une
valeur constante qui est égale à &tab[i][0].
A. SERGHINI
Cours C++ 19
• Exactement comme pour les tableaux à une dimension,
les pointeurs de pointeurs ont de nombreux avantages sur
les tableaux multi-dimensionnés.
• On déclare un pointeur qui pointe sur un objet de type
type * de la même manière qu'un pointeur, c'est-àdire
type **nom-du-pointeur;

• Par exemple, pour créer avec un pointeur de pointeur


une matrice à k lignes et n colonnes à coefficients
entiers, on écrit :

A. SERGHINI
Cours C++ 20
main()
{ int k, n;
int **tab;
tab = new int*[k];
for (i = 0; i < k; i++)
tab[i] = new int[n];
....
for (i = 0; i < k; i++)
delete [] tab[i];
delete [] tab;
}
• La première allocation dynamique réserve pour l'objet pointé par
tab l'espace mémoire correspondant à k pointeurs sur des entiers.
Ces k pointeurs correspondent aux lignes de la matrice.
• Les allocations dynamiques suivantes réservent pour chaque
pointeur tab[i] l'espace mémoire nécessaire pour stocker n entiers.
A. SERGHINI
Cours C++ 21
Exemple de tableau de chaînes:

A. SERGHINI
Cours C++ 22
Chapitre 6
Les fonctions, les références , les constantes.

A. SERGHINI
Cours C++ 1
Fonction en C ++:

Dans beaucoup de langages, on trouve deux sortes de


« modules », à savoir:
-Les fonctions, assez proches de la notion mathématique
correspondante. Notamment, une fonction dispose
d’arguments qui correspondent à des informations qui lui
sont transmises et elle fournit un unique résultat.
- Les procédures (terme Pascal) ou sous-programme
(terme Fortran ou Basic) qui élargissent la notion de
fonction.

A. SERGHINI 2
Pour élaborer une fonction C/C++, il faut coder les
instructions qu’elle doit exécuter, en respectant certaines
règles syntaxiques. Ce code source est appelé définition de
la fonction. Une définition de fonction spécifié:
o La classe de mémorisation de la fonction;
o Le type de la valeur renvoyée par la fonction;
o Le nom de la fonction;
o Les paramètres (arguments) qui sont passés à la fonction
pour y être traités;
o Les variables locales et externes utilisés par la fonction;
o D’autres fonctions invoquées par la fonction;
o Les instructions que exécute la fonction.

A. SERGHINI 3
Exemple d’illustration

Je vous propose d’examiner tout d’abord un exemple de


fonction correspondant à l’idée usuelle que l’on se fait
d’une fonction, c’est-à-dire recevant des arguments et
fournissant une valeur.

Dans cet exemple on va tester

f(x)=a x + b, avec a=4 et b=3.

A. SERGHINI 4
A. SERGHINI 5
float Fpoly (float ,int ,int);

Elle sert à prévenir le compilateur que Fpoly est une


fonction donnée par 3 arguments et une valeur de retour de
type float.

y=Fpoly (x ,m ,n);

Appel de la fonction Fpoly avec les arguments x, m et n.

A. SERGHINI 6
Arguments muets et arguments effectifs

1- Arguments muets:
Les noms des arguments figurants dans l’en-tête de la
fonction se nomment des arguments muets ou encore des
arguments formels. Leur rôle est de permettre, au sein de
la fonction, de décrire ce quelle doit faire.

2- Arguments effectifs:
Les arguments fournis (transmis) lors de l’utilisation
(l’appel) de la fonction se nomment des arguments
effectifs.

A. SERGHINI 7
L’instruction return

Voici quelques règles générales concernant cette


instruction:

- L’instruction return peut mentionner n’importe


quelle expression.
- L’instruction return peut apparaître à plusieurs
reprise dans une fonction.
- Si le type de l’expression figurant dans return est
différent du type du résultat tel qu’il a été déclaré dans
l’en-tête, le compilateur mettra automatiquement en
place des instruction de conversion.

A. SERGHINI 8
Exercice

1- Déclarez et appelez une fonction qui calcul la valeur


absolue d’entier.

2- On dispose de 4 entiers. Calculez l’ entier le plus


grand. Pour cela :
Déclarer et appeler plusieurs fois une fonction qui
compare deux entiers et qui renvoie le plus grand.

A. SERGHINI 9
Fonctions sans retour ou sans arguments

Quand une fonction ne renvoie pas de résultat, on le


précise à la fois dans l’en-tête et dans sa déclaration à
l’aide du mot clé void. Par exemple:

Déclaration : void FoncSansRt(int);

En-tête: void FoncSansRt(int a)

Naturellement, la définition d’une telle fonction ne


doit pas contenir aucune instruction return.

A. SERGHINI 10
Quand une fonction ne reçoit aucun arguments, on
place le mot clé void à la place de la liste des arguments
Par exemple:

Déclaration : float FoncSansAr(void);

En-tête: float FoncSansAr(void)

A. SERGHINI 11
Enfin, rien n’empêche de réaliser une fonction ne
possédant ni arguments ni valeur de retour.
Par exemple:

Déclaration : void FoncSansRtSansAr(void);

En-tête: void FoncSansRtSansAr (void)

A. SERGHINI 12
Fonctions récursives

Le langage C autorise la récursivité des appels de


fonctions. Celle-ci peut prendre deux aspects:
- Récursivité directe.
- Récursivité croisé.

Voici un exemple classique d’une fonction calculant


une factorielle de manière récursive.

A. SERGHINI 13
A. SERGHINI 14
Faire un programme qui calcule Cin

A. SERGHINI 15
Procédé pratique

Pour trouver une solution récursive d’un problème, on


cherche à le décomposer en plusieurs sous problèmes
de même type, mais de taille inférieurs. On procède de
la manière suivante:

1. Rechercher un cas trivial et sa solution (évaluation


sans récursivité).
2. Décomposer le cas général en cas plus simples, eux
aussi décomposables pour aboutir au cas trivial.

A. SERGHINI 16
Exemple de récursivité avec deux appels

Calcul du nème terme de la suite de Fibonacci

A. SERGHINI 17
- Prototype et caractéristiques d’une fonction en C++
 Le passage d'arguments à une fonction se fait au moyen
d'une liste d'arguments.
 La signature d’une fonction est le nombre et le type de
chacun de ses arguments.
 Surcharge : Possibilité d’avoir plusieurs fonctions ayant
. le même nom mais des signatures différentes.
Possibilité d’avoir des valeurs par défaut pour les paramètres,
qui peuvent alors être sous-entendus au moment de l’appel.
Exemple
int mult (int a=2, int b=3) { return a*b; }

mult (3,4) => 12


mult (3) => mult
mult(3,3)
(3,3) ,9
mult ( ) => mult
mult(2,3)
(2,3) ,6

A. SERGHINI
Cours C++ 18
Les Références en C++
1- Déclaration d’une référence :
En plus des pointeurs, le C++ permet de créer des références.
Les références sont des synonymes d'identificateurs.
Elles permettent de manipuler une variable sous un autre nom
que celui sous laquelle cette dernière a été déclarée.

.  Note : - Les références n'existent qu'en C++.


- Le C ne permet pas de créer des références.

Par exemple:
Si « id » est le nom d'une variable, il est possible de créer une
référence « ref » de cette variable.
Les deux identificateurs id et ref représentent alors la même
variable, et celle-ci peut être accédée et modifiée à l'aide de
ces deux identificateurs indistinctement.
A. SERGHINI
Cours C++ 19
 Toute référence doit se référer à un identificateur : il est
donc impossible de déclarer une référence sans l'initialiser.

 De plus, la déclaration d'une référence ne crée pas un


nouvel objet comme c'est le cas pour la déclaration d'une
variable par exemple. En effet, les références se rapportent à
des identificateurs déjà existants.

 La syntaxe de la déclaration d'une référence est la


suivante :
type &référence = identificateur;

 Après cette déclaration, la référence peut être utilisée


partout où l’identificateur peut l'être. Ce sont des synonymes.

A. SERGHINI
Cours C++ 20
Exemple . Déclaration de références
int i=0;
int &ri=i; // Référence sur la variable i.
ri=ri+i; // Double la valeur de i (et de ri).

Il est possible de faire des références sur des valeurs


numériques.
Dans ce cas, les références doivent être déclarées comme
étant constantes:

const int &ri=3; // Référence sur 3.


int &ri=4; // Erreur ! La référence n'est pas constante.

A. SERGHINI
Cours C++ 21
2- Lien entre les pointeurs et les références

Les références et les pointeurs sont étroitement liés. En


effet, une variable et ses différentes références ont la même
adresse, puisqu'elles permettent d'accéder à un même objet.

Utiliser une référence pour manipuler un objet revient donc


exactement au même que de manipuler un pointeur constant
contenant l'adresse de cet objet.

Les références permettent simplement d'obtenir le même


résultat que les pointeurs, mais avec une plus grande facilité
d'écriture.

A. SERGHINI
Cours C++ 22
 Cette similitude entre les pointeurs et les références se
retrouve au niveau syntaxique. Par exemple, considérons le
morceau de code suivant :

int i=0;
int *pi=&i;
*pi=*pi+1; // Manipulation de i via pi.

 Maintenant, comparons avec le morceau de code


équivalent suivant :
int i=0;
int &ri=i;
ri=ri+1; // Manipulation de i via ri.

A. SERGHINI
Cours C++ 23
Nous constatons que la référence ri peut être identifiée
avec l'expression *pi, qui représente bien la variable i.

Ainsi, la référence ri encapsule la manipulation de l'adresse


de la variable i et s'utilise comme l'expression *pi.

La différence se trouve ici dans le fait que les références


doivent être initialisées.

Les références sont donc beaucoup plus faciles à manipuler


que les pointeurs, et permettent de faire du code beaucoup
plus sûr.

A. SERGHINI
Cours C++ 24
3- Passage de paramètres par variable ou par valeur
Il y a deux méthodes pour passer des variables en paramètre
dans une fonction : le passage par valeur et le passage par
variable.
3.1. Passage par valeur
La valeur de l'expression passée en paramètre est copiée
dans une variable locale. C'est cette variable qui est utilisée
pour faire les calculs dans la fonction appelée.
C’est-à-dire:
Si l'expression passée en paramètre est une variable, son
contenu est copié dans la variable locale.
 Aucune modification de la variable locale dans la fonction
appelée ne modifie la variable passée en paramètre, parce que
ces modifications ne s'appliquent qu'à une copie de cette
dernière.
A. SERGHINI
Cours C++ 25
Exemple:

A. SERGHINI
Cours C++ 26
3.2. Passage par variable

La deuxième technique consiste à passer non plus la valeur


des variables comme paramètre, mais à passer les variables
elles-mêmes.

 Il n'y a donc plus de copie, plus de variable locale.

Toute modification du paramètre dans la fonction appelée


entraîne la modification de la variable passée en paramètre.

A. SERGHINI
Cours C++ 27
3.3. Avantages et inconvénients des deux méthodes
Les passages par variables sont plus rapides et plus économes
en mémoire que les passages par valeur, puisque les étapes de
la création de la variable locale et la copie de la valeur ne sont
pas faites.
Il faut donc éviter les passages par valeur dans les cas
d'appels récursifs de fonction ou de fonctions travaillant avec
des grandes structures de données (matrices par exemple).
Les passages par valeurs permettent d'éviter de détruire par
mégarde les variables passées en paramètre.
 Si l'on veut se prévenir de la destruction accidentelle des
paramètres passés par variable, il faut utiliser le mot clé const.
Dans ce cas, le compilateur interdira alors toute modification
de la variable dans la fonction appelée.

A. SERGHINI
Cours C++ 28
3.4. Comment passer les paramètres par variable en C ?

Il n'y a qu'une solution : passer l'adresse de la variable.


Cela constitue donc une application des pointeurs.
Exemple:

A. SERGHINI
Cours C++ 29
3.5. Passage de paramètres par référence
Le passage de paramètres par variable présente beaucoup
d’ inconvénients

 la syntaxe est lourde dans la fonction, à cause de l'emploi de


l'opérateur * devant les paramètres ;

 la syntaxe est dangereuse lors de l'appel de la fonction,


puisqu'il faut systématiquement penser à utiliser l'opérateur &
devant les paramètres.

Un oubli devant une variable de type entier implique


directement la valeur de l'entier sera utilisée à la place de son
adresse dans la fonction appelée (plantage assuré, essayez avec
scanf).
A. SERGHINI
Cours C++ 30
Le C++ permet de résoudre tous ces problèmes à l'aide des
références. Au lieu de passer les adresses des variables, il suffit
de passer les variables elles-mêmes en utilisant des paramètres
sous la forme de références. La syntaxe des paramètres devient
alors :
type identificateur(type &identificateur)
Exemple:

A. SERGHINI
Cours C++ 31
 Il est recommandé, pour des raisons de performances, de
passer par référence tous les paramètres dont la copie peut
prendre beaucoup de temps (en pratique, seuls les types de
base du langage pourront être passés par valeur).

Bien entendu, il faut utiliser des références constantes au


maximum afin d'éviter les modifications accidentelles des
variables de la fonction appelante dans la fonction appelée.

 En revanche, les paramètres de retour des fonctions ne


devront pas être déclarés comme des références constantes, car
on ne pourrait pas les écrire si c'était le cas.

A. SERGHINI
Cours C++ 32
Exemple:

Dans cet exemple, s est une référence sur une structure


constante.
Le code se trouvant à l'intérieur de la fonction ne peut donc
pas utiliser la référence s pour modifier la structure (on notera
cependant que c'est la fonction elle-même qui s'interdit
l'écriture dans la variable s).

A. SERGHINI
Cours C++ 33
Un autre avantage des références constantes pour les passages
par variables est que si le paramètre n'est pas une variable
ou, s'il n'est pas du bon type, une variable locale du type du
paramètre est créée et initialisée avec la valeur du paramètre
transtypé.

Au cours de cet appel, une variable locale est créée (la


variable i de la fonction test), et 3 lui est affectée.
A. SERGHINI
Cours C++ 34
Les Constantes en C++
Il est possible en C++ de définir des données constantes.
const double Pi = 3.141592;
Toute tentative d’écriture se soldera par un refus très net
du compilateur :
Pi += 1; // refusé !!
. Si l’on tente d’utiliser des pointeurs :
double *dp = &Pi;
on obtient une erreur
erreur.
Il faut en effet écrire
const double *dp = &Pi;
double const *dp = &Pi;

A. SERGHINI
Cours C++ 35
 Cettedéclaration signifie que *dp est constant. En
conséquence, toute occurrence de *dp dans le programme
est remplacée par la constante.

En effet, le pointeur lui-même n’est pas constant, on


peut l’incrémenter: dp++;
.
 Quant aux références, on peut parfaitement les utiliser :
En fait, si on initialise la référence sur une constante, ceci
provoque la création d’une variable provisoire.

const double &d = Pi; // valable


d++; // refuser,

A. SERGHINI
Cours C++ 36
On peut parfaitement définir des tableaux constants :
const int table[3] = { 1, 2, 3 };
et des pointeurs constants (ne pas confondre avec les
pointeurs sur des constantes) :
double *const dc = &d;

. Dans ce cas, l’opération dc++ par exemple est interdite,


puisqu’il s’agit d’un pointeur constant.
Par contre, on peut écrire :
(*dc)++; // équivaut à d++ ;
On ne peut donc pas initialiser dc avec &Pi.
Il existe aussi des pointeurs constants pointant sur des
constantes :
const int *const dcc = table;
Dans ce cas, on ne peut modifier ni dcc ni *dcc.
A. SERGHINI
Cours C++ 37

Vous aimerez peut-être aussi