View
4
Download
1
Category
Preview:
DESCRIPTION
Chap2
Citation preview
PRPAR PAR : RAOUDHA CHEBIL
Cours POO Chapitre 2 - du C au C++
ENSI AU : 2014-2015
Plan
Historique du C++
Commentaires
Types de donnes Conversions de types
Dclarations Constantes
Nouvelles possibilits dE/S
Allocation de mmoire
Fonctions Paramtres Surcharge Fonctions inline
Rfrences passage de paramtres par rfrence
Espaces de noms
2
ENSI AU : 2014-2015
Historique C++
1980 : dans le but damliorer le langage C, Bjarne Stroustrup a dvelopp le langage C with classes au laboratoire Bell.
1985 : premire dition du livre The C++ programming language .
1995-1997 : rvision du standard ANSI.
Disponible sur toutes les plateformes. Il est distribu en logiciel : domaine publique (environnement GNU),
plusieurs socits commerciales (Microsoft, Borland, Zortech, ).
3
ENSI AU : 2014-2015
Historique C++
C++ prsente des extensions par rapport au C : Qui permettent de supporter la P.O.O
Qui ne dcoulent pas de la P.O.O :
Nouvelle forme des commentaires ;
Type boolen ;
Plus grande libert dans lemplacement des dclarations ;
Surcharge des fonctions : attribution dun mme nom diffrentes fonctions ;
Nouveaux oprateurs de gestion dynamique de la mmoire : new et delete ;
Possibilit de dfinir des fonctions "en ligne" (inline), ce qui accrot la vitesse dexcution, sans perdre pour autant le formalisme des fonctions.
Passage de paramtres par rfrence
4
ENSI AU : 2014-2015
C++ versus C
Principal avantage : compatibilit C/C++
mme syntaxe de base
code C "propre" directement compilable en C++
facilit d'intgration de fichiers C++ et C dans un mme programme ( langage hybride)
Principal inconvnient : compatibilit C/C++ C++ hrite de certains choix ennuyeux du langage C !
5
ENSI AU : 2014-2015
Commentaires
.... /* je suis un super commentaire en C et je mtends sur plusieurs lignes */ ....
// je suis un super commentaire C++ sur une seule ligne ....
6
ENSI AU : 2014-2015
Types de donnes
C++ introduit le type bool pour palier cette carence en C. Il s'accompagne des mot-cls true et false.
bool flag=true;
En thorie, les rsultats des comparaisons ou des combinaisons logiques doivent tre de ce type. Toutefois, il existe des conversions implicites : de bool en numrique, true devenant 1 et false devenant 0 ; de numrique (y compris flottant) en bool, toute valeur non nulle
devenant true et zro devenant false.
7
ENSI AU : 2014-2015
Types de donnes
Dfinition implicite du type, sans avoir utiliser typedef :
struct point{
int x;
int y;
};
point p;
8
ENSI AU : 2014-2015
Conversions de types
C et C++ autorisent le mlange de donnes de diffrents types dans une mme expression.
Ncessit de convertir toutes les donnes dans un type commun avant dvaluer lexpression.
Il existe deux types de conversions :
Conversions implicites (automatique) : mises en place automatiquement par le compilateur en fonction du contexte sans lintervention du programmeur.
Conversions explicites (cast) : mises en place par le programmeur qui choisit explicitement le type dans lequel les donnes doivent tre converties.
9
ENSI AU : 2014-2015
Conversions implicites
Le compilateur tente gnralement de convertir les donnes du type le plus petit vers le type le plus large : conversion non dgradante. float X = 12.3;
int N = 5;
X = X + N; //la valeur de N est convertie en float (5.0)
Dans le cas dune affectation, le rsultat de lvaluation de lexpression droite, est converti dans le type de la variable gauche. Dans ce cas, il peut y avoir perte de prcision si le type de destination est plus faible que celui de la source : conversion dgradante. float X = 12.3;
int N;
N = X; //la valeur de X est convertie en int (12)
10
ENSI AU : 2014-2015
Conversions explicites
Le programmeur peut recourir une conversion explicite (ou cast) pour forcer la conversion dans un type particulier.
En C, lorsqu'on souhaitait raliser la conversion d'une expression dans un
type donn, on utilisait la syntaxe suivante : (type)expression (version C)
En C++, la mme conversion s'crit dsormais de la manire suivante :
type(expression) (version C++)
Il est noter qu'on peut aussi faire un mixage des deux notations : (type)(expression) (version mixte)
11
ENSI AU : 2014-2015
Conversions explicites
Exemples : int A = 3, B = 4;
float C;
C = float (A)/B;
La valeur de A est explicitement convertie en float.
La valeur de B est automatiquement convertie en float.
Le rsultat de la division (type rationnel, valeur 0.75) est affect C.
Rsultat : C=0.75
double d = 2.5;
int i;
i = int(d); // i = 2 (conversion dgradante)
12
ENSI AU : 2014-2015
Exercice
Soient les dclarations suivantes :
int n = 5, p = 9 ;
int q ;
float x ;
Quelle est la valeur affecte aux diffrentes variables concernes par chacune des instructions suivantes ?
q = n < p ; /* 1 */
q = n == p ; /* 2 */
q = p % n + p > n ; /* 3 */
x = p / n ; /* 4 */
x = (float) p / n ; /* 5 */
x = (p + 0.5) / n ; /* 6 */
x = (int) (p + 0.5) / n ; /* 7 */
q = n * (p > n ? n : p) ; /* 8 */
q = n * (p < n ? n : p) ; /* 9 */
13
ENSI AU : 2014-2015
Dlocalisation des dclarations
En C nous tions obligs de regrouper les dclarations au dbut dun bloc ou d'une fonction comme en C.
En C++, il est possible de dclarer les variables au moment o on en a besoin.
Si une variable locale est dclare dans un bloc, sa porte est limite ce bloc.
14
ENSI AU : 2014-2015
Dlocalisation des dclarations
C int i=5, itmp; int j=2;
... for (itmp=0; itmp
Les constantes
En C, la directive du prprocesseur #define permet de dfinir des constantes non types dont la valeur est connue la compilation.
En C++ le mot cl const remplace la directive du prprocesseur #define en permettant de dfinir des constantes types dont la valeur est connue la compilation.
/* constantes classiques en C */ #define P 12 #define MOI "Etudiant II1" #define MAX 100
int tab[MAX];
/* quelques constantes classiques en C++ */ const int P=12; const char MOI[]="Etudiant II1"; const int MAX=100; .... int tab[MAX];
17
ENSI AU : 2014-2015
Les constantes
Exemples :
char c;
const char *p='t';
// pointeur sur un caractere constant
char * const q=&c;
// pointeur constant sur un caractere
const char * const q=MOI;
// pointeur constant sur un caractere constant
On peut utiliser le mot cl const avec les pointeurs comme suit :
18
ENSI AU : 2014-2015
*p=c;
q=&r ;
q=&r ; *q=t;
Nouvelles possibilits DE/S
On peut utiliser, en C++, les fonctions dentres/sorties classiques du C (printf, scanf, puts, gets, putc, getc ...), condition de dclarer le fichier den-tte stdio.h. Il existe de nouvelles possibilits en C++, condition de dclarer le fichier den-tte iostream.h. Ces nouvelles possibilits ne ncessitent pas de FORMATAGE des donnes.
19
ENSI AU : 2014-2015
Nouvelles possibilits DE/S
Cout cout
Nouvelles possibilits DE/S
Cin int n; cout n; // quivalent scanf("%d",&n); int a, b; cin >> a >> b; // saisie de 2 entiers spars par un Retour Charriot
21
ENSI AU : 2014-2015
Allocation de mmoire
En langage C, la gestion dynamique de la mmoire fait appel des fonctions de la bibliothque standard telles que malloc et free.
Comme toutes les fonctions standard, celles-ci restent utilisables en C++.
C++ a introduit deux nouveaux oprateurs, new et delete, particulirement adapts la gestion dynamique d'objets. Ces oprateurs peuvent galement tre utiliss pour des "variables classiques".
22
ENSI AU : 2014-2015
Allocation de mmoire
int *ad; // dclaration dun pointeur sur un entier
ad = new int; // rservation de place en mmoire pour un entier
On aurait pu dclarer directement int *ad = new int;
char *adc;
adc = new char[100]; // rservation de place en mmoire pour 100 caract res
On aurait pu dclarer directement char *adc = new char[100];
int *adi;
adi = new int[40]; // rservation de place en mmoire pour 40 entiers
On aurait pu dclarer directement int *adi = new int[40];
delete ad; // libration de place
delete [] adc;
delete [] adi;
23
ENSI AU : 2014-2015
Allocation de mmoire
T *ptr;
ptr=new T;
/* permet d'allouer l'espace mmoire ncessaire pour un lment de type T et d'affecter ptr l'adresse correspondante.*/
// on pouvait obtenir le mme rsultat en crivant en C :
ptr= malloc(sizeof(T));
24
ENSI AU : 2014-2015
Allocation de mmoire
T *ptr; ptr= new T[N]; /* alloue l'emplacement ncessaire pour un tableau de N lments de type T et place l'adresse (de dbut) dans ptr. En C, on obtenait le mme rsultat en crivant :*/ ptr=malloc(sizeof(T)*N);
25
ENSI AU : 2014-2015
Allocation de mmoire
Pour librer lespace allou par loprateur new :
T *ptr; ptr=new T; delete ptr;
T *ptr; ptr=new T[N]; delete[]ptr;
26
ENSI AU : 2014-2015
Pile/Tas (Stack/Heap)
Mmoire alloue de manire statique (Pile)
Variables globales Arguments Valeurs de retour
Mmoire Alloue Dynamiquement (Tas)
Cell * ConstruireListe(int taille) { int i; Cell *cour, *tete; tete = NULL; for (i=taille; i >0; i--) { cour = (Cell*) malloc ( sizeof (Cell)); cour->valeur = i; cour->suivant = tete; tete = cour; // Point darrt 2 } return tete; }
void main () { Cell * tete ; tete = ConstruireListe(4); }
Pointeurs
struct Cell { int valeur; Cell * suivant; }
27
ENSI AU : 2014-2015
ENSI AU : 2014-2015
29
ENSI AU : 2014-2015
Typage et prototypage obligatoires des fonctions
La dclaration des arguments se fait toujours lintrieur des parenthses. Le typage des fonctions est obligatoire, et possde un sens fort : on ne peut pas retourner une valeur si la fonction a t dclare void, et rciproquement, on doit retourner une valeur dans le cas contraire.
Exemple :
void f(int i, char* c) ;
int f(int i);
.
f(); // f ne peut pas tre appele avec des arguments.
.
30
ENSI AU : 2014-2015
Conversions de type lors de lappel dune fonction
Lors dun appel de fonction, le compilateur C++ compare les types des arguments effectifs avec ceux des arguments muets.
Dans le cas de non-conformit, le compilateur effectue les conversions ncessaires pour que la
fonction reoive des arguments dont les types sont conformes la dclaration. Les conversions possibles, dans ce cadre, ne sont pas limites aux conversions non
dgradantes ; elles couvrent toutes les conversions autorises lors dune affectation.
Exemple:
double ma_fonction(int u, float f); void main() { char c; int i, j; float r; double r1, r2, r3, r4; r1 = ma_fonction( i, r ); // appel standard r2 = ma_fonction( c, r); // appel correct, c est converti en int r3 = ma_fonction( i, j); // appel correct, j est converti en float r4 = ma_fonction( r, j); // appel correct, r est converti en int // et j est converti en float }
31
ENSI AU : 2014-2015
Surdfinition des fonctions
La surdfinition des fonctions permet de dclarer et de dfinir des fonctions ayant un nom identique mais des signatures diffrentes.
Attention toutefois : le type de retour ne fait pas partie de la signature. La surdfinition doit par consquent prserver le type de retour, elle ne touche qu'aux paramtres.
Exemple : int fonction(int n) { ... } int fonction(float x) { ... } void fonction(int n, int p) { ... } float fonction(float x, int n) { ... } void fonction(float x, int n) { ... } // erreur : m me signature
Remarques :
La surdfinition peut se rvler particulirement intressante lorsqu'on souhaite viter des conversions de types indsirables lors du passage des paramtres.
32
ENSI AU : 2014-2015
Surdfinition des fonctions
Exemples :
void essai (int, double) ; // essai I
void essai (double, int) ; // essai II
int n, p ; double z ; char c ;
.....
essai(n,z) ; // appelle essai I
essai(c,z) ; // appelle essai I, aprs conversion de c en int
essai(n,p) ; // erreur de compilation,
33
ENSI AU : 2014-2015
Rgles de recherche dune fonction Surdfinie
Le compilateur recherche la "meilleure correspondance" possible.
Il y a plusieurs niveaux de correspondance :
1) Correspondance exacte : le type de largument pass correspond exactement au type du paramtre formel.
2) Correspondance avec promotion numrique : c..d. avec un recours une conversion de types, essentiellement char et short en int et float en double.
3) Conversions standards : il s'agit des conversions lgales en C++ : c'est--dire celles qui peuvent tre imposes par une affectation (sans oprateur de cast). Dans ce cas, il peut s'agir de conversions dgradantes puisque, notamment, toute conversion d'un type numrique en un autre type numrique est accepte.
Si plusieurs fonctions conviennent, il y a erreur de compilation due l'ambigut. De mme, si aucune fonction ne convient aucun niveau, il y a aussi erreur de compilation.
34
ENSI AU : 2014-2015
Surdfinition des fonctions
La surdfinition suivante provoque une erreur de compilation car C++ n'a pas prvu de distinguer int de const int.
void f(int) ; // fI
void f(const int) ; // fII
Notez bien quici lerreur tient la seule prsence des dclarations de f , indpendamment dun appel quelconque.
35
ENSI AU : 2014-2015
Surdfinition des fonctions
En revanche, si on considre les dclarations suivantes : void f(int *) ; // fI
void f(const int *) ; // fII
int n = 3 ;
const int p = 5 ;
Cette fois, la distinction entre int * et const int * est justifie.
En effet, on peut trs bien prvoir que fI modifie la valeur pointe par le paramtre effectif, tandis que fII n'en fait rien.
Cette distinction est possible en C++, de sorte que : f(&n) ; // appelle f I
f(&p) ; // appelle fII
36
ENSI AU : 2014-2015
Paramtres avec valeur par dfaut
C++ procure la facilit de fournir une valeur par dfaut aux paramtres.
Il existe cependant une restriction importante dans la mise en uvre des paramtres par dfaut :
partir du moment o un paramtre possde une valeur par dfaut, tous les paramtres suivants doivent galement en possder une.
En effet, dans le cas contraire, cela pourrait poser des problmes pour le compilateur :
int f(int a=0, int b, int c=0); .... i=f(1, 2, 3); // OK j=f(4); // toujours OK ~ f(0, 4, 0) k=f(5, 6); // argh ! ~ f(5, 6, 0) // ou f(0, 5, 6) ? // non respect de la contigit
En revanche, l'exemple suivant est valide : void f(double x, double y=0.0, double z=0.0); .... f(a); // OK ~ f(a, 0.0, 0.0) f(a, b); // OK ~ f(a, b, 0.0) f(a, b, c); // OK ~ f(a, b, c) // respect de la contigut
37
ENSI AU : 2014-2015
Paramtres avec valeur par dfaut
void f1(int n = 3) // par dfaut le paramtre n vaut 3 void f2(int n, float x = 2.35) // par dfaut le paramtre x vaut 2.35 void f3(char c, int n = 3, float x = 2.35) // par dfaut le paramtre n vaut 3 void main() { char a = 0; int i = 2; float r = 5.6;
f1(i); f1(); f2(i,r); f2(i) f2(); f3(a, i, r); f3(a, i); f3(a);
}
38
ENSI AU : 2014-2015
// largument n vaut 2, linitialisation par dfaut est ignore // largument n prend la valeur par dfaut
// les valeurs par dfaut sont ignores // le second paramtre prend la valeur par dfaut //interdit
// les initialisations par dfaut sont ignore s // le troisime paramtre prend la valeur par dfaut // le deuxime et le troisime paramtres prennent les valeurs par dfaut
Paramtres anonymes
C++ permet de dclarer des paramtres anonymes, c'est--dire des paramtres dont seul le type est spcifi dans la signature.
Exemple :
int f (int x, char *y)
version C (nommage obligatoire )
int f(int, char *);
version C++ (paramtres anonymes)
39
ENSI AU : 2014-2015
Rfrence (alias)
On peut dsormais dfinir des variables rfrence, c'est--dire des variables que l'on peut identifier d'autres variables.
int n,m ; int& i=n ; // i variable rfrence sur n i=m; // Signifie n=m et non que i devient une rfrence sur m !
40
ENSI AU : 2014-2015
Rfrence (alias)
Exemple 1 :
int n;
int &p = n; // p est une rfrence sur n
// p occupe le mme emplacement mmoire que n
n = 3;
cout
Passage par rfrence
Absence de conversion Ds lors quune fonction prvoit un passage de paramtres par rfrence, les
conversions de type lappel ne sont plus autorises : le type du paramtre effectif doit correspondre exactement au type du paramtre formel.
void f(int& n) ; // f reoit un entier par rfrence
float x ;
...
f(x) ; // appel illgal
Cette rgle ne sapplique pas dans le cas o les paramtres formels sont constants
43
ENSI AU : 2014-2015
Passage par rfrence
Cas dun paramtre effectif constant Ds lors quune fonction prvoit un passage de paramtres par rfrence, elle
nadmettra pas de constantes comme paramtres effectifs au moment de son appel.
void f(int& n) ; // f reoit un argument par rfrence
...
f(3) ; // incorrect : f ne peut pas modifier une constante
const int c = 5;
f(c) ; // incorrect : f ne peut pas modifier une constante
Cette rgle ne sapplique pas dans le cas o les paramtres formels sont constants
44
ENSI AU : 2014-2015
Passage par rfrence
Cas dun paramtre formel constant Considrons une fonction ayant le prototype suivant : void f(const int& n) ;
const int c = 5 ; float x;
f(3) ; // correct
f(c) ; // correct
f(x) ; /* correct : f reoit par rfrence une vari able
temporaire contenant le rsultat de la conversion d e x en int */
Ce cas est quivalent un passage de paramtres par valeur sans copie des paramtres effectifs dans les paramtres formels.
45
ENSI AU : 2014-2015
Macros et fonctions
Deux notions voisines en C : macros et fonctions
Nom + liste darguments entre ( )
En C, lorsqu'on a un traitement court et que le temps dexcution est primordial, on fait gnralement appel une macro plutt qu une fonction.
Les instructions correspondant une macro sont incorpores dans le programme chaque appel.
Tandis que les instructions correspondant une fonction sont "gnres" une seule fois par le compilateur ; chaque appel, il y aura seulement mise en place des instructions ncessaires pour tablir la liaison entre le programme et la fonction.
46
ENSI AU : 2014-2015
Macros et fonctions
Exemple de macro :
#define MAX(a,b) (((a)>=(b))? (a) : (b))
Les macros peuvent entraner des effets de bords dsastreux
lorsqu'elles sont mal dfinies. D'autre part, il n'y a aucun contrle sur le type des arguments.
Exp : Une macro dfinie par : carre(x) x * x
et appele par : Carre(++a)
gnrera les instructions : ++a * ++a
47
ENSI AU : 2014-2015
Macros et fonctions
Macro
Gain en temps dexcution
Perte despace mmoire ;
Pas de contrle sur les types des donnes ;
Risque davoir des rsultats inattendus.
Fonction
Gain despace mmoire
Contrle de type des donnes
Pas de risques deffet de bord
Perte de temps dexcution d au mcanisme dappel
48
ENSI AU : 2014-2015
Fonctions en ligne
En C++, l'introduction du mot-cl inline va nous permettre d'viter le recours aux macros.
le compilateur se charge de la conversion en macro
#define MAX(a,b) (((a)>=(b))? (a) : (b)) inline int Max (int a, int b) {return (a>=b) ? a : b);}
Lorsquune fonction est dclare inline, le compilateur la traite comme sil
sagissait dune macro (remplacement de code) dans la mesure du possible (fonction peu volumineuse).
Les fonctions inline permettent davoir la scurit dune fonction ordinaire (pas deffet de bord) et la rapidit dune macro.
49
ENSI AU : 2014-2015
Fonctions en ligne
Une fonction en ligne se dfinit et s'utilise comme une fonction ordinaire, la seule diffrence qu'on fait prcder son en-tte de la spcification inline.
#include // ancien pour sqrt #include using namespace std ; /* dfinition dune fonction en ligne */ inline double norme (double vec[3]) { int i ; double s = 0 ;
for (i=0 ; i
Fonctions en ligne
/* exemple dutilisation */ main() { double v1[3], v2[3] ;
int i ; for (i=0 ; i
Fonctions en ligne 53
Fonction en ligne
Contrle de type des donnes
Gain de temps dexcution
Perte despace mmoire
ENSI AU : 2014-2015
Structuration dun programme C++
Un programme C++ est constitu de :
Une fonction principale main() : cest le point dentre au programme.
Des fichiers d'en-tte (extension .h) qui regroupent les dclarations de types, de classes et les prototypes des fonctions
Des fichiers sources (extensions : .c, .cpp) comportent le code proprement dit : le corps des fonctions et des mthodes, la dclaration de variables, d'objets.
54
ENSI AU : 2014-2015
Inclusion des bibliothques
La manire classique d'inclure les fichiers d'en-tte des bibliothques du C tait la suivante :
#include #include #include
En C++, il n'est plus ncessaire de spcifier l'extension sur les fichiers d'en-tte standards du C, mais il faut spcifier que c'est un fichier de la librairie C en ajoutant le caractre 'c' devant.
#include #include
Lorsquil sagit dune bibliothque C++, pas dextension
#include
55
ENSI AU : 2014-2015
Espaces de noms
En C, il tait difficile de faire cohabiter plusieurs versions d'une mme structure de donnes.
Pour viter le conflit de noms, on tait oblig de modifier les noms de chaque structure
C++ propose un moyen simple de rsoudre ce problme : les espaces de noms.
Les espaces de noms permettent de dfinir une unit cohrente dans laquelle on peut regrouper les dclarations des diffrents objets (types, constantes, variables, fonctions).
namespace A { //dclarations int point; }
56
ENSI AU : 2014-2015
Espaces de noms
Lorsqu'on utilise plusieurs espaces de noms comportant des identificateurs identiques ; on peut lever lambiguit en faisant appel l'oprateur de rsolution de porte :
namespace Version1 { struct Pile { ... }; } namespace Version2 { struct Pile { ... }; } .... void main () { Version1::Pile p1; Version2::Pile p2; .... }
57
ENSI AU : 2014-2015
Espaces de noms
On peut aussi spcifier l'espace de nommage par dfaut l'aide du mot-cl using. using namespace version1; Pile p1; //l'identificateur p1, employ seul correspondra celui dfini dans l'espace de noms version1
Remarque : Tous les identificateurs des fichiers en-tte standard sont dfinis dans lespace de noms std ; Il est donc ncessaire de recourir systmatiquement linstruction : using namespace std ; /* utilisation des fichiers en-tte standard */
58
ENSI AU : 2014-2015
Recommended