Vous êtes sur la page 1sur 118

Faculté des sciences SMA Semestre 5

Kénitra Octobre 2014

Cours d'Introduction à la programmation


orientée objet en C++
A. Souhar

Ce cours se reparti en deux parties:


Le premier plus (Et un Rappel de la programmation C).
Bases de la programmation objet.
Fonc%ons  d’entrée/sor%e  
• Les  fonc)ons  d’entrée/sor)e  standards  sont
déclarées  dans  la  librairie  <stdio.h>  .

• L’appel  à  la  librairie  <stdio.h>  s’effectue  par  la


direc)ve  de  compila)on  include  :
#include <stdio.h>
• On  u)lise:
– Fonc)on  d’affichage:  prinC
– Fonc)on  de  saisie:  scanf
Fonc%on  prin1  
• Transfert  le  contenu  d’une  variable,  d’une  constante  
ou  le  résultat  d’une  expression  sur  la  sor%e  standard  
stdout  (l’écran).  

• Ecriture  formatée  :  les  objets  à  afficher  sont  


conver%s  selon  le  format  spécifié.  

• Syntaxe  
printf(’’format’’,expr1,expr2,...,exprn);

– expr1,  expr2,  ...,  exprn  :  les  valeurs  à  afficher.  


– format  :  une  chaîne  de  caractères  qui  con%ent  
le  format  d’affichage.  
Format  d’affichage  est  cons%tuée  par  :  
– Le  texte  à  afficher.

– Des  séquences  d’échappement  pour  le  contrôle


de  l’affichage.

– Des  spécificateurs  de  format


• Annoncer  le  format  avec  lequel  l’expression
doit  être  affichée.
• A  chaque  expression  on  associe  un
spécificateur  de  format.
• Un  spécificateur  de  format  est  cons)tué  du
symbole  %  suivie  d’un  caractère  qui  indique  
le  format  d’affichage  .    
Spécificateurs  de  format  
•  Caractères    :  %c  

•  Chaînes  de  caractères    :  %s  

•  En)ers    
   %d  :  en  décimal  
   %o  :  en  octale  
   %x  :  en  hexadécimal  
•  Réels    
   %f  :    ±ddd.dddddd            6  chiffres  après  ‘.’  
   %e  :    ±d.dddddde±ddd    
   %x.yf  :  y  chiffres  après  ‘.’  et  x  chiffres  en  tout  
       
Fonc%on  scanf  
• Saisit  les  données  à  par)r  du  clavier  et  les  stocke  aux  
adresses  fournies  comme  arguments.  

scanf(’’format’’,&v1,&v2,…,&vn) ;

– v1,  v2,...,vn  :    variables  qui  reçoivent  les  données  


saisies.  

– Format:  Chaîne  de  caractères  qui    con%ent    les  


spécificateurs  de  format  de  chaque  variable.  

• Les  données  saisies  au  clavier  doivent  être  séparées  par  


des  espaces  ou  des  retour  chariot…  
Spécificateurs  de  format  
• Caractères    :  %c  

• Chaînes  de  caractères    :  %s  

• En)ers  :  %d  
     
• Réels  :  %f        
Entrées-­‐sor%es  en  C++  
• Un  programme  qui  u%lise  les  flux  standard  
d'entrée-­‐sor%e  doit  comporter  la  direc%ve  
       #include  <iostream.h>  

   ou  bien  
•  si  vous  u%lisez  un  compilateur  récent  :  
     #include  <iostream>  
     using  namespace  std;      
Entrées-­‐sor%es  en  C++  
•  Les  flux  d'entrée-­‐sor%e  sont  représentés  dans  
les  programmes  par  les  deux  variables,  
prédéclarées  et  préini%alisées,  suivantes  :  

•  cin,  le  flux  standard  d'entrée,  qui  est  associée  


au  clavier  du  poste  de  travail,  

•  cout,  le  flux  standard  de  sor%e,  qui  est  associé  


à  l’écran  du  poste  de  travail,    
Entrées-­‐sor%es  en  C++  
Les  écritures  et  lectures  se  font  en  u%lisant  des    
opérateurs  :  

• <<,  appelée  opérateur  d'injec0on  (  injec0on


de  données  dans  un  flux  de  sor0e),

• >>,  appelé  opérateur  d'extrac0on  (  extrac0on


de  données  d'un  flux  d'entrée).  
Sor%es  en  C++  
• le  programmeur  n'a  pas  à  s'encombrer  avec  des  
spécifica%ons  de  format.  
• La  syntaxe  d'un  injec%on  de  donnée  sur  la  sor%e  
standard  cout  est  :  
• cout  <<  expression  ;  

• ((cout  <<  exp1  )  <<  exp2  )  <<  exp3  ;  


Ou  bien  simplement  
• cout  <<  exp1  <<  exp2  <<  exp3  ;      
Entrées  en  C++  
• le  programmeur  n'a  pas  à  s'encombrer  avec  des  
spécifica%ons  de  format.  
• La  syntaxe  d'un  injec%on  de  donnée  sur  la  sor%e  
standard  cout  est  :  
• cin  >>  variable  ;  

• ((cin  >>  var1  )  >>  var2  )  >>  var3  ;  


Ou  bien  simplement  
• cin  >>  var1  >>  var2  >>  var3  ;      
Entrées-­‐sor%es  en  C++  
#include  <iostream>  
using  namespace  std;  
void  main()  {  
   float  x;  
   int  n;  
   cout  <<  "Donner  x  et  n  :  ";  
   cin  >>  x  >>  n;  
   cout  <<  x  <<    "  *  "    <<  n  <<  "  =  "  <<  x*n  <<  "\n";  
}  
Mémoire  de  l’ordinateur  
•  Composée  de  N  cases  mémoires  de  k  bits  

•  Chaque  case  est  iden7fiée  par  une  adresse  unique  entre  0  et  N  
K  bits     adresse    

… 0
… 1
N  emplacements    

… 2
.
.
.
.
.

… N-1
Variables  et  mémoire  
• Lorsqu’on  déclare  une  variable,  une  associa;on  sera  définie
entre  le  nom  de  ce=e  variable  et  un  emplacement  mémoire
où  seront  stockée  ses  valeurs.

• Quand,  on  u;lise  dans  le  code  une  variable  deux  opéra;ons
seront  effectuées:
1.Recherche  de  l’adresse  qui  correspond  à  la  variable.  
2.Placer  ou  retourner  la  valeur  contenue.  

C++  permet  de  réaliser    ces  deux  opéra;ons:  


1. &x  retourne  l’adresse  de  x  dans  la  mémoire.
2. *(&x)  une  déréférence  est  effectuée,  retournant  la
valeur  trouvée  dans  la  mémoire  (c’est  à  dire  x).
No7on  de  pointeur  
•  Un  pointeur  est  une  variable    dont  la  valeur  est  une  adresse  
d’un  emplacement  mémoire  .    

Valeur     Adresse_k  

Adresse_k   Adresse_p  
No7on  de  pointeur:  exemple  
• Le  pointeur  qui  se  trouve  à  l’adresse  1020  pointe  sur  l’espace
d’adresse  1001

Zone  de  données   1000  

100   1001  

1002  

Zone  Heap   1001   1020  


Pointeurs  et  types  de  variables(1)  
• La  taille  de  l’espace  pointé  dépend  du  type  de  son  contenu  
– char  :  1  octet  
– int        :  4  octets    
– float  :  4  octets  
– double  :  8  octets  

• L’adresse  d’un  emplacement  est  donc  liée  au  type  de  la  valeur  
qu’il  con;ent,  on  a  ainsi:  
– Pointeurs  d’en;er  
– Pointeurs  de  caractères    
– Pointeurs  de  réels  
– Etc.  
Pointeurs  et  types  de  variables(2)  

Une  variable  simple  occupe  un  ou  plusieurs  cases  mémoires  et    
donc  plusieurs  adresses.  

                       14652   ‘S’          1465.2098981  


1002  

1004  

1006  

1010  

1011  

1012  
1007  

1008  

1013  
1003  

1005  

1009  
1001  

int   char   float  


Pointeurs  et  types  de  variables(3)  

                             14652   ‘S’   1465.2098981  

?  

?  

?  
1002  

1004  

1006  

1010  

1011  

1012  
1007  

1008  

1013  
1003  

1005  

1009  
1001  

int   char   float  


Pointeurs  et  types  de  variables(4)  

1001  

1009  
1006  
                             14652   ‘S’   1465.2098981  
1002  

1004  

1006  

1010  

1011  

1012  
1007  

1008  

1013  
1003  

1005  

1009  
1001  

int   char   float  


Pointeur  u7le  
• Pointeur    NULL    
– Représente  un  pointeur  invalide  i.e.,  un  pointeur  qui  ne
pointe  sur  aucun  espace  mémoire.
Déclara7on  des  pointeurs  
•  Syntaxe  
nom_type * nom_pointeur ;

type  du  contenu  de  


l’emplacement  pointée  
indique  que  la  variable  
déclarée  est  un  pointeur.   Nom  de  la  variable  
•  Exemples   pointeur  

int *ptr_entier ; //pointeur sur un entier


long int *ptr_long;//pointeur sur un entier long
double *ptr_double;//pointeur sur un réel double
char *ptr_carac ; //pointeur sur un caractère
Ini7alisa7on  d’un  pointeur  
• L’ini7alisa7on  consiste  à  affecter  une  adresse  à  la  variable  
pointeur  

• Un  pointeur  peut  être  ini7alisé  par  :  

–  L’adresse  d’une  variable  existante    à  l’aide  de  l’opérateur  &

–  Une  nouvelle  adresse,  à  l’aide  de  la  fonc7on  new  


Ini7alisa7on  à  l’aide  de  l’opérateur  &  

• L’opérateur  &  permet  d’obtenir  l’adresse  de  son  opérande  

si  var  est  une  variable  d’un  certain  type  alors  &var est  
son  adresse  

• L’ini7alisa7on  d’un  pointeur  avec  l’adresse  d’une  autre  variable  


selon  la  syntaxe  suivante:

type X ;
type* ptr_X ;
ptr_X= &X ; /* affectation de l’adresse
de X à ptr_X */
Ini7alisa7on  à  l’aide  de  l’opérateur  &  

• Exemple

void main()
{
/* X contient la valeur 25 */ 1000  
int X = 25; X   25   1001  
int *ptr_X ; 1002  

}
ptr_X   ?   1020  
Ini7alisa7on  à  l’aide  de  l’opérateur  &  

• Exemple    

void main()
{
/* X contient la valeur 25 */ 1000  
int X = 25; X   25   1001  
int *ptr_X ; 1002  

ptr_X = &X ;
/* ici ptr_X contient l’adresse de X */ ptr_X   1001   1020  

}
Ini7alisa7on  à  l’aide  de  new  
•  new  :Permet  de  réserver  un  espace  mémoire  de  certaine  
taille  et  de  retourner  son  adresse.    

•  Un  pointeur  peut  être  ini7alisé  par  l’adresse  de  cet  


emplacement.  

•   Cet  emplacement  mémoire  lui  est  réservée  au  cours  de  


l’exécu7on  du  programme.    

•  Syntaxe    

nom_type  *ptr_X  ;  

ptr_X=  new  nom_type;  


Ini7alisa7on  à  l’aide  de  new  

• Exemple

void main()
{ 1000  

int *ptr_X ; 1001  

1002  
1003  

}
ptr_   ?   1020  
Ini7alisa7on  à  l’aide  de  new  

• Exemple    
void main()
{
int *ptr_X ; 1000  
1001  
/* allocation mémoire pour une
variable entière X */ 1002  
1003  
ptr_X = new int;

/* on suppose que l’opérateur new


a retourné l’adresse 1000*/ ptr_X   1000   1020  

}
Indirec7on:  Accès  à  l’espace  pointé  
•  L’opérateur  d’indirec7on  *  permet  de  délivrer  la  valeur  contenue  dans  
l’espace  pointé  par  un  pointeur.  

•  Si  ptr  est  un  pointeur  de  type  t  alors  *ptr  est  une  variable  de  type  t  qui  
con7ent  la  valeur  contenue  dans  l’adresse  ptr  

100     1003  
*ptr_int  con;ent  la  
valeur  100  

1003   ptr_int  
Indirec7on:  Accès  à  l’espace  pointé  

• Sur  la  variable  *ptr,  on  peut  effectuer  toutes  les  


opéra7ons  permises  sur  le  type  t:  

– Lecture                :    cin  >>  *ptr;  

– Affichage          :    cout  <<  *ptr;

– Opérateurs    :    =,+,*,  /,  ==,  Etc.


Indirec7on:  Accès  à  l’espace  pointé  
•  Exemple  
#include<iostream.h>
int main()
{
int * ptr_int;
int x;
ptr_int = new int;
cin >> *ptr_int;
x= *ptr_int*2;
*ptr_int=x;
cout << *ptr_int;
return 0;
}
Libéra7on  d’un  espace  

• L’opérateur  delete  permet  de  libérer  un  espace  


mémoire  qui  a  été  alloué  par  l’opérateur  new,  

• Ce\e  fonc7on  est  appelée  une  fois  qu’on  a  plus  


besoin  de  cet  espace.  

• Syntaxe  
             nom_type *p;  
       delete  p;  
Arithmé7que  des  pointeurs  

• Somme  d’un  pointeur  avec  un  en7er  

 Si  ptr  est  un  pointeur  de  type  t  alors  ptr+  i  est  un  un  
pointeur  de  même  type  que  ptr  qui  pointe  sur  
l’espace  d’adresse  ptr+i*sizeof(t)  

• Un  déplacement  n’a  de  sens  que  si  ptr+i  pointe  un    


espace  de  même  type  que  celui  pointé  par  ptr    
Références  

• C++  a  introduit  un  nouveau  constructeur  de  


type  qui  est  une  référence  à  un  objet.  

• Une  référence  est  traitée  comme  un  pointeur,  


sauf  que  la  déréférence  est  automa7quement  
effectuée.  

• Syntaxe  :    nom_type  &p;  


Références  
•  Exemple  :  
 int      i  =  3;    //  ini7alisa7on  faculta7ve  
 int&    r  =  i;    /*    ini7alisa7on  obligatoire  lors  de  la    
                   déclara7on  */          

r  est  assimilé  à  un  autre  nom  de  la  variable  i  .  

En  fait:    r  est  pointeur  sur  i,  qu’on  manipule  comme  une  


variable  de  type  int  .  

On  modifiant  i,  on  modifie  r  et  inversement  .  


                     
Références  

• Exemple  :  
 int      x  ,  y;  

 int&    r  =  x;    //  ini7alisa7on  obligatoire  lors  de  


       //  la  déclara7on            

 r  =  y;    //  copie  la  valeur  de  y  dans  x  


                     
Les fonctions
Définition
• Une fonction est un ensemble d’instructions, indépendant,
qui réalise une tâche bien précise et peut renvoyer une
valeur

• Une fonction peut être considérée comme une boîte noire


qui reçoit en entrée des données et fournit des résultas en
sortie.

Données Fonction Résultats


Exemples
• Fonction main: fonction obligatoire, qui permet de diriger
l’exécution du programme

• Fonction scanf: permet d’alimenter les programmes par des


valeurs

• Carre(x): renvoie le carrée d’un réel

• Echange (a,b): permute les valeurs de ses paramètres.


Déclaration des fonctions

• La déclaration d’une fonction en C est constituée par deux


parties :

– La partie interface, appelée aussi prototype, spécifie l’apparence


de la fonction : le nom, les données et les résultats fournies par la
fonction.

– La partie corps spécifie le comportement de la fonction i.e., les


instructions à exécuter sur les données pour obtenir les résultats.
Prototype de fonctions

• L’interface est constituée par trois éléments, chacun joue


un rôle particulier.

• Syntaxe

type_retour nom_fonction(liste des paramètres)

type de la valeur que la


fonction doit retour
Entrées et sorties de la
fonction
Nom de la fonction
Type de retour
• Type de la valeur que la fonction doit retourner à la fonction appelante.

• Peut être
– L’un des types de bases: int, float, char, etc.
– Un pointeur sur l’un des types de bases

• Dans le cas où la fonction n’ a aucune valeur à retourner on utilise void


comme type de retour.

• Exemples

void Afficher(...)
int factoriel(...)
float puissance(...)
char* puissance(...)
Liste des paramètres
• Paramètres formels: données nécessaires et
résultats attendus.

• Pour chaque paramètre on doit préciser:

–L’identificateur (nom)
–Le type
–La nature : fixe ou variable.
Paramètres fixes
• Un paramètre fixe est invariant par la fonction: la valeur en entrée est
la même qu’en sortie, même s’il est modifié à l’intérieur de la fonction.

• Les données nécessaires à une fonction sont en générale considérés


comme des paramètres fixes.

• Syntaxe

type_retour nom_fonction(type1 id1, type2 id2, ...)

• Exemple

int somme (int a, int b)


Paramètres variables
• Un paramètre variable peut être modifié par la fonction, la valeur en
entrée n’est pas toujours la même que celle en sortie.

• Les résultats attendus de la fonction sont considérés en générale


comme des paramètres variables.

• Syntaxe

type_retour nom_fonction(type1 *id,..,...)

• Exemple

void somme (int a, int b, int *s)


Exemples
• a et b : paramètres fixes
int somme (int a, int b) ;

• a et b : paramètres fixes, s : paramètre variable, sans type de retour


void somme(int a, int b, int *s) ;

• fonction sans paramètres et sans valeur retour


void afficher() ;

• a et b : paramètres variables, sans valeur de retour


void echange (int *a, int* b);

• Pointeur comme valeur de retour


int* produit (int a, int b);
Corps de la fonction
• Bloc d’instructions (entre {} )
• Syntaxe
{
déclarations des variables locales
instructions
return expression ;
}

• Variables locales
– Déclarées dans la fonction
– Ne sont pas visibles à l’extérieure

• Instructions : Opérations effectuant la tâche de la fonction.

• return
– Renvoie la valeur d’une expression à la fonction appelante.
– Interrompt l’exécution de la fonction appelée.
Emplacements des fonctions
• Avant la fonction main
void fonc1(...)
{
...
}
...
void main()
{
...
}

• Prototype avant la fonction main et le corps après main


void fonc1(...);
...
void main()
{
...
}
void fonc1(...)
{
...
}
Comment écrire une fonction
• Pour écriture une fonction on doit déterminer les
éléments suivants:

– type de retour : Quel est le type de l’expression que la fonction


doit retourner ?

– Paramètres fixes: Quels sont les données dont la fonction a


besoin pour effectuer sa tâche ?

– Paramètres variables: Quels sont les résultats que la fonction doit


fournir ?

– Corps: Quelles sont les instructions qui permettent d’obtenir les


résultats à partir des données ?
Exemples

• Maximum de deux entiers : sans valeur de retour

• Valeur absolue d’un réel : avec valeur de retour

• Permutation des valeurs de deux variables


Exemples
• Maximum de deux entiers : sans valeur de retour

void Maximum (int a, int b, int* Max)


{
*Max = a ;
if (a < b)
*Max = b ;
}
• Valeur absolue d’un réel : avec valeur de retour

float absolue (float x)


{
float val;
val = x ;
if (x<0)
val = -x ;
return val;
}
Exemples
• Valeur absolue d’un réel : avec valeur de retour

float absolue (float x)


{
if (x<0)
return (-x) ;
return x;
}
• Permutation des valeurs de deux variables:
void Echange (int *a, int *b)
{
int c;
c=*a;
*a=*b;
*b=c;
}
Appel de fonctions

• L’appel de fonctions consiste à appliquer la fonction appelée


sur les arguments fournis par la fonction appelante .

• Différence entre paramètres formels et paramètres effectifs :

– Paramètres formels: paramètres qui sont définis lors de la déclaration


de la fonction

– Paramètres effectifs (arguments): les paramètres spécifiés lors de


l’appel de la fonction
Appel de fonctions
• Principe

Fonction
appelante Fonction appelée

Paramètres
effectifs
Suspension de
l’exécution Exécution de la
fonction

Valeur de retour
Reprise de
l’exécution

Retour vers
l’appelant
Appel de fonctions
• Syntaxe
– Appel comme une instruction simple, la valeur de retour(si elle existe) est
ignorée
nom_fonction (paramètres effectifs)

– Appel comme paramètre dans une instruction :

• Affectation à une variable

variable = nom_fonction (paramètres effectifs)

• Paramètre effectif d’une autre fonction

fonc(nom_fonction (paramètres effectifs))

• Un facteur dans une expression

Var1 = nom_fonction (paramètres effectifs)* var2


Appel de fonctions
• Exemple
#include <stdio.h>
float absolue( float a ) Paramètre
{ formel
if(a<0)
return(-a);
return a ;
}
void main()
{ Paramètre
float x, y, Max, val ; effectif
printf(" Entrer la valeur de x : ") ;
scanf("%f ", &x) ;
/* appel de la fonction absolue*/
val=absolue( x );
printf("%f", val) ;
}
Appel de fonctions
• Exemple
#include <stdio.h>
Maximum ( int a,int b ,int * max )
{
*max=a ;
if (a < b)
*max = b
}
void main()
{
int x, y, max ;
printf(" Entrer la valeur de x et y : ") ;
scanf(" %d%d", &x,&y) ;

/* appel de la fonction max */


Maximum(x,y,&max)
printf (" %d", max)
}
Appel de fonctions
• Exemple
#include <stdio.h>
Maximum ( int a,int b ,int * max )
{
Paramètres
*Max=a ;
formels
if (a>=b)
*Max = b
}
void main()
{
float x, y, max ;
printf(" Entrer la valeur de x et y : ") ;
scanf(" %d%d", &x,&y) ;
/* appel de la fonction max */ Paramètres
Maximum(x,y,&max) effectifs

printf (" %d", max)


}
Appel de fonctions
• Remarques

– Lors de l’appel d’une fonction on doit respecter les contraintes


suivantes :

• Le nombre de paramètres effectifs doit être le même que celui des


paramètres formels.

• L’ordre des paramètres effectifs doit être le même que celui des
paramètres formels.

• Les paramètres effectifs et les paramètres formels doivent être de


même type.
Passage des paramètres
• Lors de l’appel d’une fonction, la fonction appelante transmet les
paramètres effectifs à la fonction appelée

• Deux modes de transmission:


– Passage par valeur :
• Transmission d’une copie du paramètre effectif
• Pas d’effet sur le paramètre en question, même si l fonction modifie sa valeur.

• Concerne les paramètres fixes

– Passage par adresse:


• Transmission de l’adresse de l’emplacement mémoire du paramètre effectif.

• La fonction peut modifier le paramètre en question.


• Concerne les paramètres variables
Passage des paramètres

• Étapes lors du passage des paramètres

– Copie des valeurs des paramètres dans la pile

– Allocation de l’espace mémoire, dans la pile, pour les paramètres et


les variables locales de la fonction appelée.

– Exécution du corps de la fonction

– Stockage des résultats de la fonction dans la pile.

– Récupération des valeurs sur la pile


Exemple 1 : passage par valeur
int x=20, y ;
y = f(x) ;

Mémoire
centrale

int f(int x)
x = 20 {
Y=40 x= x+x ;
1. Copier x sur return x ;
la pile }
2. Exécuter la
fonction

4. Récupérer le résultat de 3. Stocker le résultat


la pile sur la pile

x = 20
x= 40

Pile
Exemple 2 : passage par adresse
int x=20;
f2(&x) ;

void f2(int * x)
{
x = 20 *x= *x + *x ;
x = 40 1. Copier &x sur la }
pile
2. Exécuter la
fonction

3. lire la valeur du paramètre


à partir de la M. C. (&x)
&x 4. Stocker le résultat dans la
M.C. &x
Pile
Portée des variables
• Une variable est caractérisée par :

– La portée: c’est la partie du programme où la variable est définie,


visible et aussi utilisable

– La durée de vie:
• Durée pendant laquelle la donnée est conservée en mémoire
• Dépend de la portée

• Deux catégories de variables


– Variables locales
– Variables globales
Variables locales
• Une variable locale
– Définie dans les fonctions et les blocs

– Portée: fonctions ou blocs dans les quelles elle est définie

– Durée de vie : durée de vie de la fonction ou du bloc

• Exemple
int f(int a, int b)
{
int i,j; i, j existent dans (1), (2) et (3)
………… 1
{ k, l existent dans (2)
int k, l;
……… 2
}
………… 3
}
Variables locales
• Classe d’allocation: définit la portée et la durée de vie d’une variable

• Trois types d’allocation


– auto : crée la variable à l’entrée de la fonction ou du bloc et la détruit
à la sortie

– register : idem à auto, la variable sera placée dans un registre

– static :
• La variable crée aura une durée de vie égale à celle du programme

• La visibilité reste la même


Variables locales
• Exemple

#inlude <stdio.h>
void fonct()
{
static int x=0;
int y=0;
printf(“x = %d, y = %d\n”,x++, y++);
}

main()
{
int i ;
for (i=0;i <10; i++)
{
printf(’’ iteration = %d ’’, i)
fonct();
}
}
Variables globales
• Propriétés d’une variable globale:
– Définie à l’extérieur de tous blocs et de toutes fonctions, y compris de
la fonction main

– Visible et utilisable partout dans le programme

– Durée de vie égale à celle du programme

– Une variable globale non initialisée est automatiquement initialisée à 0

• Utilisable dans le cas où la plupart des fonctions du


programme ont besoin d’accéder à une même variable.
Variables globales
• Exemple

#inlude <stdio.h>
int x=999;
const float PI= 3.14;
void fonct()
{
printf(“x = %d\n”,x);
}

main()
{
printf(“x = %d\n”,x);
fonct();

}
Arguments par défaut
• Une fonction peut recevoir à l’appel un nombre de paramètres
effectifs inférieur à celui des paramètres formels.

• Les paramètres manquants reçoivent une valeur par défaut,


signalée par = .

• Exemple :
void f(int ,float = 1.0, char = ‘x’);

• Les appels suivants sont correctes:


f(5);
f(5, 3.14);
f(5, 3.14, ‘c’);
• Si un paramètre manque, il est remplacé par celui fourni à la
déclaration:
f(5); <=============> f(5, 1.0, ‘x’);
f(5, 3.14); <=============> f(5, 3.14, ‘x’);
Surcharge de fonctions
• Plusieurs fonctions peuvent avoir le même nom.

• De ces fonctions, celle à appeler est déterminée au moment de


l’appel par le biais du prototype.

• Exemple :
void f(int);
void f(float);
void f(int, int);

Chacun des appels suivants correspond à la bonne fonction :


f(1);
f(3.14);
f(5, 3);
Passage des paramètres par
référence
• L’usage des références est essentiellement prévu pour le
passage des paramètres sans copie (quant).

• Une fonction qui permute deux réels en C peut être :


void permuter(float* x, float* y)
{
*x = *x + *y;
*y = *x - *y;
*x = *x - *y;
}

• En C++, :
void permuter(float& x, float& y)
{
x = x + y;
y = x - y;
x = x - y;
}
Fonction en ligne
• A l’appel d’une fonction en ligne, il n’y a pas lieu à une
rupture de séquence comme c’est le cas pour une fonction
ordinaire.
• Pour plus d’efficacité, le compilateur remplace cet appel par
son corps en mettant les arguments à la place des paramètres
formels.
• En C++, la syntaxe est:
inline void permuter(float& x, float& y)
{
x = x + y;
y = x - y;
x = x - y;
}

• A utiliser uniquement pour des fonctions fréquemment appelées,


de petites tailles et rapides.
Constructeurs  de  types  

Les  données  dans  un  programme  peuvent  être  :  

• Simples  :  on  les  représente  par  des  types  simples  (int,


char,  float,  double).

• Homogènes  :  on  les  représente  par  les    Tableaux  .

• Complexes  ou  hétérogènes  :  on  les  représente  par  les    


Constructeurs  de  types  .  
Constructeurs  de  types  
• Défini>on  :
– Un  constructeur  de  type  permet  de  construire  un  nouveau  type  à
par@r  des  types  de  bases,  les  structures  sont  un  exemple.

– Une  structure  permet  de  construire  un  type  pour  des  données
formées  de  composantes  pouvant  être  hétérogènes.  Ces  composantes
s’appellent  aussi  membres  ou  champs.

• Exemples  :
– type  date  :    jour,  mois,  année.
– type  étudiant  :    nom,  prénom,  CNE,  CIN.

• Lors  de  son  implémenta>on,  on  dis>ngue  deux  niveaux:


– Construc>on:  défini@on  de  la  forme  du  type  (son  nom,  les  types  et  les
noms  des  composants).

– Exploita>on:  déclara@on  et  manipula@on  des  variables  de  ce  type.


Structures    
• Syntaxe    :
struct      nom_structure    
{  
 type_1          nom_champ_1  ;  
 type_2    nom_champ_2  ;  
 .  
 .  
 type_n    nom_champ_n  ;  
};  

—  nom_structure  :  nom  de  la  structure  (nouveau  type).    

—  nom_champ_1,  nom_champ_2,...,nom_champ_n  sont  les  noms  


des  membres  qui  caractérisent  la  donnée.  

—  type_1,  type_2,...,  type_n  sont  les  types  des  différents  membres.  


Accès  aux  membres  de  Structures    
• Pour  désigner  un  membre  d’une  structure  on  u@lise:  
– L’opérateur  de  sélec@on  point  (.)  pour  les  variables  sta@ques,  
– L’opérateur  (->)  pour  les  variables  dynamiques.  

• Syntaxe
nom_variable.nom_champ; /*Variable statique */
nom_variable->nom_champ; /*Variable dynamique */

• Exemple
struct complexe{  
double re;
double im;};
complexe z1,*z2;
z2= &z1 ;
z1.im accède à la partie imaginaire de z1
Z2->im accède à la partie imaginaire de z2  
Exemple  1  

#include  <iostream.h>   int  main()  


struct  complexe  
 {  
 {  
 double  re;    complexe  z;  
 double  im;  
 };    ini@aliser(2.5,z);    
void  ini@aliser(double  r,complexe&  z){    afficher(z);  
 z.re  =  r;  z.im=0.0;  
 }  
       return  0;  
void  afficher(complexe&  z){  
 cout  <<  z.re  <<"    "<<  z.im;    }  
 }  
Structures  améliorées    

La  no@on  de  structure  été  améliorée  pour  y  incorporer  les  


fonc@ons  d’accès  à  ses  différents  champs.  

Ainsi,  avec  les  structures  on  peut  définir  un  nouveau  type  qui  
regroupe  :  
•  Les  différents  champs  de  la  structure,  

•  Les  fonc@ons  agissantes  sur  ces  champs  (appelées  aussi  


méthodes).  
Exemple  2  

#include  <iostream.h>   int  main()  


struct  complexe  
 {  
 {  
 double  re;    complexe  z;  
 double  im;  
 z.ini@aliser(2.5);    
 void  ini@aliser(double  r){    z.afficher();  
   re  =  r;  im=0.0;  
   }  
       return  0;  
 void  afficher(){  
   cout  <<  re  <<"    "<<  im;    }  
   }  
 };  
Exemple  2  
struct  complexe  
 {  
 …   //  fonc@on  d’accès  
 void  ini@aliser(double  r){  
//  les  champs  re  et  im  seront  ceux  
   re  =  r;  im=0.0;  
   }   //  de  la  variable  u@lisée  lors  de  
 …   //  l’appel  de  la  fonc@on  
 };  

int  main()  
 {  
 complexe  z;  
 z.ini@aliser(2.5);   //exécuter  la  fonc@on  ini@aliser  
 …   //  appliquée  à  la  variable  z  
 }  
Structures  améliorées    

Dans  l’exemple  précédent,  la  fonc@on  ini@aliser  a  été  incorporer  


complètement  dans  la  structure  :  son  prototype  et  sons  corps.  

Dans  ce  cas,  la  fonc@on  ini@aliser  sera  inline  :  Pour  Chaque  appel  
le  compilateur  génère  (c-­‐à-­‐d  recopie)  les  différentes  instruc@ons  
de  la  fonc@on.  

Si,  on  cherche  un  véritable  appel  de  fonc@on,  on  se  contente  de  
déclarer  uniquement  le  prototype  de  la  fonc@on  comme  membre  
de  la  structure.  
Exemple  3  
#include  <iostream.h>  
struct  complexe   int  main()  
 {    {  
 double  re;  
 double  im;  
 complexe  z;  
 void  ini@aliser(double  r);  
 void  afficher();    z.ini@aliser(2.5);    
 };    z.afficher();  
void  complexe::ini@aliser(double  r){  
 re  =  r;  im=0.0;          return  0;  
 }  
void  complexe::afficher(){  
 }  
 cout  <<  re  <<"    "<<  im;  
 }  
Exemple  3  
struct  complexe  
 {  
 …   //  ini@aliser  fonc@on  d’accès    
 void  ini@aliser(double  r);  
//declarée  membre  de  la  structure  
 …  
 };  
//void  la  fonc@on  ne  retourne  rien.  
//complexe    elle  porte  sur  la  
//  structure  nommée  complexe.  
//::  opérateur  de  résolu@on  portée    
void  complexe::ini@aliser(double  r){  
 re  =  r;  im=0.0;   //de  la  structure.  
 }   //ini@aliser(double  r)ceae  fonc@on  
//a  un  double  comme  argument.  
Classes  et  Objets  

Dans  l’exemple  précédent,  la  fonc@on  main  con@ent  l’instruc@on:  


 complexe  z;    

 z  est  une  variable  de  type  complexe.  

z  est,  alors,  composé  de  2  champs  (re  et  im)et  u@lisable  par  deux  
fonc@ons  d’accès  (ini@aliser  et  afficher).  

Dans  la  terminologie  objet:  


z  est  appelé  objet  et  la  défini@on  d’un  type  objet  s’appelle  une  classe.  
On  dit  aussi  que  z  est  une  instance  de  la  classe  complexe.    

Ce  qui  revient  a  remplacé  le  mot  réservé  struct  par  le  mot  class  .  
Exemple  4  
class  complexe  
                 {  
 double  re;  
 double  im;   classe  :  aspect  sta@que,  descrip@f  et  unique  
 void  ini@aliser(double  r);  
 void  afficher();  
 };  
…  
int  main()  
 {  
 complexe  z1,z2;  
 …  
 return  0;   objet:  aspect  dynamique,  existen@el  et  mul@ple  
 }  
Exemple  4  
#include  <iostream.h>   int  main()  
class  complexe    {  
 {    complexe  z;  
 double  re;  
 double  im;  
 void  ini@aliser(double  r);    z.ini@aliser(2.5);    
 void  afficher();    z.afficher();  
 };  
void  complexe::ini@aliser(double  r){        
 return  0;  
 re  =  r;  im=0.0;    }  
 }  
void  complexe::afficher(){   /*ces  fonc@ons  ne  sont  
 cout  <<  re  <<"    "<<  im;   plus  accessible  dans  
 }   la  fonc@on  main*/  
Classes  et  Objets  

les  membres  de  la  classe  sont  privées  c-­‐à-­‐d  que  l’écriture  de  z.re=1.5;  
ou  z.afficher();  n’est  pas  possible  en  dehors  de  la  classe.  
Ces  membres  ne  sont  accessibles  que  depuis  les  méthodes  de  la  
classes.  

Dans  l’exemple  précédent:    


 Dans  le  main,  les  appels  des  méthodes  suivantes:  
   z.ini@aliser(2.5);  
   z.afficher();  
 provoquent  des  erreurs  lors  de  la  compila@on  du  programme.  

On  ne  peut  y  accéder  aux  membres  privés  d’une  classe  que  par  
l’intermédiaire  d’une  de  ses  méthodes  publiques.  
Exemple  5  
#include  <iostream.h>  
class  complexe   int  main()  
 {  
 {  
 double  re;  
 double  im;    complexe  z;  
                 public:  
 void  ini@aliser(double  r);    z.ini@aliser(2.5);    
 void  afficher();    z.afficher();  
 };  
void  complexe::ini@aliser(double  r){  
       return  0;  
 re  =  r;  im=0.0;  
 }    }  
void  complexe::afficher(){  
 cout  <<  re  <<"    "<<  im;  
 }  
Exemple  6  
#include  <iostream.h>  
class  complexe   int  main()  
 {double  re;   {  
 double  im;   complexe  z1,z2;  
                 public:   z1.ini@aliser(1.5);  
 void  ini@aliser(double  r);       z2.ini@aliser(3.5);  
 void  afficher();  
 void  addi@onner(complexe&  z);   z1.afficher();  
 };   z1.addi@onner(z2);  
void  complexe::ini@aliser(double  r)   z1.afficher();  
 {re  =  r;  im=0.0;}  
void  complexe::afficher(){cout  <<  re  <<"    "<<im;}   return  0;  
}  
void  complexe::addi@onner(complexe&  z)  
 {re  +=  z.re;  im+=z.im;}  
Envoi  de  message  
‘‘envoyer  un  message’’  consiste  à  appliquer  la  méthode  associée  à  la  
classe  de  l’objet  des@nataire.  

class  complexe  
 {…  
 void  addi@onner(complexe&  z);  
 };  
void  complexe::addi@onner(complexe&  z)  
 {re  +=  z.re;        im  +=  z.im;}  
int  main()  
{  
complexe  z1,z2;   z1 : destinataire le receveur du message
z1.addi@onner(z2);   additionner : message
z2 : argument
…  
Au lieu de : additionner(z1, z2);
return  0;  
}  
Accès  à  ses  propres  membres  
Dans  une  méthode,  l’objet  à  travers  lequel  on  appelle  est  désigné  implicitement  :  
 void  complexe::addi@onner(complexe&  z){  
 re  +=  z.re;  
 im+=z.im;  
 }  

On  peut  aussi  employer  une  désigna@on  explicite  :  this  


 void  complexe::addi@onner(complexe&  z){  
 this-­‐>re  +=  z.re;  
   this-­‐>im+=z.im;  
 }  
int  main()  
{  
complexe  z1,z2;  
z1.addi@onner(z2);    //  dans  cet  appel  on  aura  this  =  z1    et    z=  z2  
…  
return  0;  
}  
Exemple  6  
#include  <iostream.h>  
class  complexe  
 {double  re;  
 double  im;   int  main()  
                 public:   {  
 void  ini=aliser(double  r,  double  i);   complexe  z1,z2,z3;  
 void  ini=aliser(double  r);  
 void  ini=aliser();     z1.ini=aliser(2.5,  1.5);  
 void  afficher();   z2.ini=aliser(3.5);  
 };   z3.ini=aliser();  
void  complexe::ini=aliser(double  r,  double  i)  
 {re  =  r;  im=i;}   z1.afficher();  
void  complexe::ini=aliser(double  r)   z2.afficher();  
 {re  =  r;  im=0.0;}   z3.afficher();  
void  complexe::ini=aliser()  {re  =  im=0.0;}   return  0;  
void  complexe::afficher(){cout  <<  re  <<"    "<<im;}   }  
Exemple  7  
#include  <iostream.h>  
class  complexe  
 {double  re;  
 double  im;   int  main()  
                 public:   {  
 void  ini=aliser(double  r,  double  i=0);   complexe  z1,z2,z3;  

 void  ini=aliser();     z1.ini=aliser(2.5,  1.5);  


 void  afficher();   z2.ini=aliser(3.5);  
 };   z3.ini=aliser();  
void  complexe::ini=aliser(double  r,double  i)  
 {re  =  r;  im=i;}   z1.afficher();  
z2.afficher();  
void  complexe::ini=aliser()  {re  =  im=0.0;}   z3.afficher();  
void  complexe::afficher(){cout  <<  re  <<"    "<<im;}   return  0;  
}  
Exemple  8  
#include  <iostream.h>  
class  complexe  
 {double  re;  
int  main()  
 double  im;  
{  
                 public:  
complexe  z1(2.5,  1.5);  
 complexe(double  r,double  i=0);  
complexe  z2  (3.5);  
 complexe  ();    
complexe  z3;  
 void  afficher();  
 };  
z1.afficher();  
z2.afficher();  
complexe::complexe  (double  r,double  i)  
z3.afficher();  
 {re  =  r;  im=i;}  
return  0;  
}  
complexe::complexe  ()  {re  =  im=0.0;}  

void  complexe::afficher(){cout  <<  re  <<"    "<<im;}  


Exemple  9  
#include  <iostream.h>  
class  complexe   int  main()  
 {double  re;   {  
 double  im;   complexe  z1(2.5,  1.5);  
                 public:   complexe  z2  (3.5);  
 complexe(double  r=0,double  i=0);   complexe  z3;  

 void  afficher();   z1.afficher();  


 };   z2.afficher();  
z3.afficher();  
complexe::complexe  (double  r,double  i)   return  0;  
 {re  =  r;  im=i;}   }  

void  complexe::afficher(){cout  <<  re  <<"    "<<im;}  


Exemple  10  
#include  <iostream.h>  
class  complexe  
 {double  re;  
int  main()  
 double  im;  
{  
                 public:  
complexe  z1(2.5,  1.5);  
 complexe(double  r=0,double  i=0):  
complexe  z2  (3.5);  
   re(r)  ,  im(i)    {  }  
complexe  z3;  
 void  afficher();  
z1.afficher();  
 };  
z2.afficher();  
z3.afficher();  
void  complexe::afficher(){cout  <<  re  <<"    "<<im;}  
return  0;  
}  
Exemple  11  
int  main()  
#include  <iostream.h>   {  
complexe  *z1,*z2,*z3;  
class  complexe  
z1=new  complexe(2.5,1.5);  
 {double  re;   z2=new  complexe(3.5);  
 double  im;   z3=new  complexe();  
                 public:  
 complexe(double  r=0,double  i=0):   z1-­‐>afficher();  
       re(r)  ,  im(i)    {  }   z2-­‐>afficher();  
z3-­‐>afficher();  
 void  afficher();  
 };   return  0;  
}  

void  complexe::afficher(){cout  <<  re  <<"    "<<im;}  


Exemple  12  
#include  <iostream.h>  
class  complexe  
 {double  re;   int  main()  
 double  im;   {  
                 public:   complexe  z1(2.5,  1.5);  
 complexe(double  r=0,double  i=0):   complexe  z2  (3.5);  
       re(r)  ,  im(i)    {  }   complexe  z3;  
 complexe  operator+(complexe);   z3=z1+z2;  
             void  afficher();   //z3=z1.operator+(z2);    
 };  
z1.afficher();  
complexe  complexe::operator+(complexe  z)       z2.afficher();  
z3.afficher();  
   {complexe  s(re+z.re,  im+z.im);  
return  0;  
     return  s;  }   }  

void  complexe::afficher(){cout  <<  re  <<"    "<<im;}  


Exemple  13  
#include  <iostream.h>  
class  complexe  
                     {double  re;  
                       double  im;   int  main()  
{  
                 public:  
complexe  z1(1,  3.1);  
 complexe(double  r=0,double  i=0):re(r),im(i){  }   complexe  z2  (1.2,  2);  
                         complexe  operator+(complexe);   complexe  z3=z2;  
                         complexe  operator*(complexe);   z1=z2+z3;    
           void  afficher();   z2=z2+z3*z1;  
                     };   z3=z1*z2+complex(1,  2);  
complexe  complexe::operator+(complexe  z)
z1.afficher();  
 {return  complexe  s(re+z.re,  im+z.im);}  
z2.afficher();  
z3.afficher();  
complexe  complexe::operator+(complexe  z)       return  0;  
{complexe  p(re*z.re-­‐  im*z.im,  re*z.im+  im*z.re);   }  
return  p;}  
void  complexe::afficher(){cout  <<  re  <<"    "<<im;}  
Fonc=on  amie  
Exemple  14  

int  main()  
{  
complexe  z1(2.5,  1.5);  
complexe  z2  (3.5);  
complexe  z3;  

cout  <<''z1''<<'='<<  z1;  


cout  <<  ''z2=''<<  z2;  
cout  <<  ''z3=''<<  z3;  
return  0;  
}  
Exemple  15  

int  main()  
{  
complexe  z;  

cin  >>  z;    


cout  <<  ''z=''<<  z;  
return  0;  
}  
Exemple  11  
int  main()  
{  
complexe  *z1,*z2,*z3;  
z1=new  complexe(2,1);  
z2=new  complexe(3.5);  
z3=new  complexe();  

cout  <<  ''z1=''<<  z1;  


cout  <<  ''z2=''<<  z2;  
cout  <<  ''z3=''<<  z3;  

delete  z1,z2,z3;  
return  0;  
}  
Exemple  11  
int  main()  
{  
complexe  z[  ];  
z=new  complexe[4];  

for(int  i=0;i<4;i++)  
         cout  <<  z[  i];  

delete  [  ]z;    
return  0;  
}  
Relations entre classes
• La relation de composition:
• Etudier à travers l’exemple de la relation
entre la classe matrice et la classe
vecteur.

• La relation d’héritage:
• Etudier par le biais de la relation qui lie la
classe polynôme et la classe vecteur.
Université Ibn Tofaïl A.U. :2012/2013
Faculté des sciences SMA-Semestre 5
Kénitra Durée : 1 h 30 mn
Examen
Programmation en C++

On défini un nombre complexe par un couple de nombres réels, le premier membre


appelé re (sa partie réelle) et le second membre appelé im (sa partie imaginaire).

1°) Définir une classe Complexe pour représenter des nombres complexes muni d’un
constructeur (un seul) pour initialiser un nombre complexe: Un nombre complexe peut
être initialisé à partir des valeurs de sa partie réelle et de sa partie imaginaire. Il peut
aussi être initialisé à partir d’un réel qui correspond donc à sa partie réelle, sa partie
imaginaire étant nulle. Enfin, en l’absence d’information, le nombre complexe est
initialisé à zéro.

2°) Ajouter à cette classe deux méthodes pour additionner deux nombres complexes :
la première appelée additionner consiste à ajouter un complexe à un complexe existant.
La seconde appelée somme consiste à créer et à retourner un nouveau complexe étant
la somme de deux complexes.

3°) Ajouter à la classe Complexe (définie à la question 1) deux méthodes une nommée
conj retournant le conjugué du nombre complexe et l’autre nommé mod retournant le
module du nombre complexe.

4°) Ajouter à la classe Complexe (définie à la question 1) une méthode appelée afficher
qui accède à re et im sans les modifier en affichant leurs valeurs sous la forme re + i m
(si re et im sont non nuls) ou re (si im est nul) ou bien 0 (si re=im=0).

5°) Surcharger l’opérateur de multiplication * , l’opérateur de division / et l’opérateur


d’injection << pour permettre l’écriture du code suivant :
int main(){ z3=z1*z2 ;
Complexe z1(1.5, 3.5); cout <<’’z3=’’<< z3 <<’’\n’’;
Complexe z2(2.5) ; z4=z1/z2 ;
Complexe z3, z4 ; cout <<’’z4=’’<< z4 ;
return 0 ;}
Université Ibn Tofaïl A.U. :2012/2013
Faculté des sciences SMA-Semestre 5
Kénitra Durée : 1 h 30 mn
Examen
Programmation en C++

On définit un nombre complexe par un couple de nombres réels, le premier membre


appelé re (sa partie réelle) et le second membre appelé im (sa partie imaginaire).

1°) Définir une classe Complexe pour représenter des nombres complexes, munie d’un
constructeur (un seul) pour initialiser un nombre complexe: Un nombre complexe peut
être initialisé à partir des valeurs de sa partie réelle et de sa partie imaginaire. Il peut
aussi être initialisé à partir d’un réel qui correspond donc à sa partie réelle, sa partie
imaginaire étant nulle. Enfin, en l’absence d’information, le nombre complexe est
initialisé à zéro.

2°) Ajouter à cette classe deux méthodes pour additionner deux nombres complexes :
la première appelée additionner consiste à ajouter un complexe à un complexe existant.
La seconde appelée somme consiste à créer et à retourner un nouveau complexe étant
la somme de deux complexes.

3°) Ajouter à la classe Complexe (définie à la question 1) trois méthodes une nommée
conj retournant le conjugué du nombre complexe, la deuxième nommé mod retournant
le module du nombre complexe et la dernière nommée arg retournant son argument.

4°) Ajouter à la classe Complexe (définie à la question 1) deux méthodes une appelée
afficherCartesienne qui accède à re et im sans les modifier en affichant leurs valeurs
sous la forme re + i m (si re et im sont non nuls) ou re (si im est nul) ou bien 0 (si
re=im=0) et l’autre appelée afficherPolaire qui affiche le complexe sous sa forme
polaire ( ||z|| exp(i*α) où ||z|| son module et α son argument).

5°) Surcharger l’opérateur de multiplication * , l’opérateur de division / et l’opérateur


d’injection << pour permettre l’écriture du code suivant :
int main(){ z3=z1*z2 ;
Complexe z1(1.5, 3.5); cout <<’’z3=’’<< z3 <<’’\n’’;
Complexe z2(2.5) ; z4=z1/z2 ;
Complexe z3, z4 ; cout <<’’z4=’’<< z4 ;
return 0 ;}

1/2
N.B : Quand c’est nécessaire vous pouvez utiliser les fonctions mathématiques
prédéfinies, dans la bibliothèque <math.h>, suivantes :

double sqrt(double t) ; // retourne la racine carré de t


double sin(double t) ; // retourne le sinus de t
double cos(double t) ; // retourne le cosinus de t
double tan(double t) ; // retourne la tangente de t
double atan2(double y, double x) ;// retourne α en radians avec –π<α< π
// où y=sin(α) et x=cos(α)
double atan(double t) ; // retourne tan-1(t) dans l’intervalle –π/2 et π/2 en radians
double asin(double t) ; // retourne sin-1(t) dans l’intervalle –π/2 et π/2 en radians
double acos(double t) ; // retourne cos-1(t) dans l’intervalle–π/2 et π/2 en radians

2/2
Université Ibn Tofaïl A.U. :2012/2013
Faculté des sciences SMP-Semestre 5
Kénitra Durée : 1 h 30 mn
Examen
Programmation

A°) Un point est définit par un couple de nombres réels x et y, qui détermine ses
coordonnées dans le plan. Considérons pour représenter ce point en ‘‘C++’’ la structure
suivante :

struct Point{
float x ; // le membre x représente l’abscisse du point
float y ; // le membre y représente l’ordonné du point
};
1°) Donner les corps des fonctions suivantes :

void placer(Point & p, float abs, float ord) qui change les valeurs de x et y du point p par

les deux réels fournit en arguments.

void afficher(Point p) qui affiche les valeurs de x et y du point p sous la forme (…,…)

2°) Réécrire les deux fonctions lorsqu’elles sont définies à l’intérieure de la structure :

struct Point {
float x; float y;
void placer(float abs, float ord){…}
void afficher(){…}
};

B°) Un segment est définit par deux points qui déterminent ses extrémités.
Considérons pour représenter ce segment la structure suivante :

struct Segment {
Point p1; //le membre p1 représente la première extrémité du segment
Point p2; //le membre p2 représente la deuxième extrémité du segment
};
Donner les corps des fonctions suivantes :

1°) void definir(Segment & s, Point ext1, Point ext2) qui initialise le segment s par

les deux points ,préalablement définit, fournit comme arguments.

void afficher(Segment s) qui affiche les valeurs des extrémités du segment s

sous la forme [(…,…),(…,…)]

1/2
2°) float longueur(Segment s) qui calcule et retourne la distance qui sépare les

deux extrémités du segment s.

3°) void deplacer(Segment& s, float dx, float dy) qui permet de translater le

segment s de dx selon l’axe des abscisses et de dy selon l’axe des ordonnées.

4°) int appartient(Segment s, Point p) qui retourne 1 si le point p appartient au

segment s ou 0 sinon.

5°) Point projection(Segment s, Point p) qui retourne le point d’intersection du

segment s avec la droite perpendiculaire(au segment s) passante par p.

6°) int seCouper(Segment s1, segment s2) qui retourne 1 si les deux segment s1

et s2 se coupent ou 0 sinon.

int aligner(Segment s1, segment s2) qui retourne 1 si les deux segment s1 et

s2 appartiennent à la même droite et ont une extrémité commune ou 0 sinon.

N.B :
* Quand c’est nécessaire vous pouvez utiliser la fonction mathématique
prédéfinie, dans la bibliothèque <math.h>, suivante :
float sqrt(float t) ; // retourne la racine carré de t

** L’utilisation des classes à la place des structures est également permise, mais
dans ce cas les prototypes des fonctions précédentes, devenant des méthodes, doivent
être modifiés.

2/2
Université Ibn Tofaïl A.U. :2013/2014
Faculté des sciences SMA-Semestre 5
Kénitra Durée : 1 h 30 mn
Examen
Programmation en C++

1°) Soit A une matrice carrée n*n . Ecrire un programme qui :


a°) Calcule le nombre des éléments non nuls de A.
b°) Calcule la somme des éléments au-dessus de la diagonale (c’est-à-dire les
éléments a ij où i<j ).
c°) Calcule le produit des éléments diagonaux (a 11 , a 22 , … , a nn ).

2°) Soit B une matrice carrée n*n tridiagonale représentée par la figure suivante :
b 11 b 12
b 21 b 22 b 23
b 32 b 33 b 34

b n,n-1 b nn
Cette matrice peut être rangée dans un tableau linéaire T, comme l’indiquent les
flèches, soit : T[1]= b 11 , T[2]= b 12 , T[3]= b 21 , T[4]= b 22 , …
a°) Quelle est la taille optimale du tableau T.
b°) Etablir l’expression qui donne i en fonction de j et k telle que : T[i]=B[j][k] .

3°) Un vecteur peut être définit avec un entier représentant sa dimension et un tableau
dynamique de réels contenant ses éléments.
Définir une classe Vecteur pour représenter des vecteurs, muni d’un constructeur pour
initialiser sa dimension et pour allouer l’espace mémoire nécessaire au tableau.
Ajouter à cette classe une méthode pour additionner deux vecteurs : elle consiste à
créer et à retourner un nouveau vecteur étant la somme des deux (vecteurs).

4°) Une matrice peut être définit avec deux entiers représentant les nombres de lignes
et de colonnes et un tableau dynamique de vecteurs contenant ses éléments.
Définir une classe Matrice pour représenter des matrices, muni d’un constructeur
pour initialiser son nombre de lignes et celui de colonnes et allouer l’espace mémoire
nécessaire.
Ajouter à cette classe une méthode pour additionner deux matrices : elle consiste à
créer et à retourner une nouvelle matrice étant la somme des deux (matrices).

1/1
Université Ibn Tofaïl A.U. :2013/2014
Faculté des sciences SMA-Semestre 5
Kénitra Durée : 1 h 30 mn
Examen de rattrapage
Programmation en C++

1°) Un monôme est définit par un réel désignant son coefficient et un entier désignant sa puissance.
Écrire une classe représentant des monômes munie :
 d’un constructeur (un seul) pour initialiser un monôme: Un monôme peut être initialisé à partir des
valeurs de son coefficient et de sa puissance. Il peut aussi être initialisé à partir d’un réel qui correspond
donc à son coefficient, sa puissance étant nulle. Enfin, en l’absence d’information, le monôme est
initialisé à zéro.
 d’une méthode somme qui consiste à additionner un monôme à un monôme existant et qui renvoie un
message signalant l’impossibilité s’ils ne sont pas du même degré.
 d’une méthode nommée coefficient qui retourne le coefficient du monôme et une deuxième nommée
puissance qui retourne sa puissance.
 d’une méthode d’affichage.

2°) Un polynôme peut être définit par un entier désignant son degré et un tableau dynamique contenant
ses coefficients.
3
Exemple : P(X)= 1.5 + 3.5 X
3 L’attribut degré
L’objet polynôme P
1.5 0 0 3.5
L’attribut tableau des coefficients
Écrire une classe représentant des polynômes munie :
 d’un constructeur.
 d’une méthode ajouter qui reçoit un monôme en entrée et l’ajoute au polynôme existant.
 d’une méthode somme qui reçoit un polynôme en entrée et l’additionne au polynôme existant.
 d’une méthode d’affichage.

3°) Écrire un programme qui utilise la classe polynôme pour afficher la somme des deux polynômes
2 3
suivants : P(X)= 1 + 3 X et Q(X)= 0.5 + X+ 5 X

4°) Un polynôme peut être définit par un tableau dynamique d’objets monômes.
2 3
Exemple : P(X)= 0.5 + 1.5 X+ 2.5 X + 3.5 X

L’objet polynôme P 0.5 1.5 2.5 3.5


0 1 2 3

Écrire, alors, une classe représentant des polynômes munie d’un constructeur, d’une méthode somme qui
reçoit un monôme en entrée et l’additionne au polynôme existant et d’une méthode d’affichage.

Vous aimerez peut-être aussi