Vous êtes sur la page 1sur 64

Programmation en C++

MASTER PHYSIQUE
de la Matière
et de Rayonnement

Soufiane DAHMANI
@ : s.dahmani@ump.ac.ma

S. DAHMANI
1
Cours C++
Chapitre 3
Les types de base ,Pointeur, Tableau,

S. DAHMANI
Cours C++ 2
Les types int et double

 Nous avons déjà étudié précédemment les


type int et double pour stocker
respectivement un entier et un réel.

S. DAHMANI
Cours C++ 3
Le type char
 Le type char est un type prédéfini du langage
C++.
 Il permet de stocker un caractère.
 Il est codé en général sur 8 bits. On peut faire
des tests sur le caractère :
 if(c>='A' && c<='Z') permet par exemple de
tester si un caractère est une lettre
majuscule. On peut transférer un char dans
un int. On récupère alors le code ASCII du
caractère.
S. DAHMANI
Cours C++ 4
Exemple 1 : utilisation du type char

S. DAHMANI
Cours C++ 5
Codage des caractères

 Chaque caractère est codé en général sur 8


bits sous la forme d'un code ASCII.
 Le code ASCII est un système de
représentation des caractères où chaque
caractère est codé par un entier entre 0 et
127.
 On peut récupérer ce code en mettant un
caractère dans un entier.

S. DAHMANI
Cours C++ 6
Exemple 2 : le codage des caractères

S. DAHMANI
Cours C++ 7
Explications
 On demande à l'utilisateur de saisir un
caractère dans une variable a.
 On récupère le code ASCII de a en mettant a
dans une variable entière x.
 On affiche ce code ASCII par un cout.
 Exécution
 Saisir une lettre : H
 Le caractère ASCII de H est : 72
 Saisir une lettre :w
 Le caractère ASCII de w est : 119
S. DAHMANI
Cours C++ 8
Comparaison sur les char
 Lorsqu'on effectue des comparaisons sur les
char, on compare en fait les codes ascii.
 On peut tester si un caractère c est une
majuscule par le test (x>='A' && x<='Z').
 On peut tester si un caractère c est une
minuscule par le test (x>='a' && x<='z').
 On peut tester si un caractère c est un
chiffre par le test (x>='0' && x<='9').

S. DAHMANI
Cours C++ 9
Exemple 3 : Comparaison sur les char

S. DAHMANI
Cours C++ 10
Transformation char-int

 On peut effectuer des opérations de base sur


les char : addition et soustraction.
 Ces opérations sont en fait réalisée sur les
codes ascii.
 Si c est un chiffre c-'0' est la valeur de
l'entier correspondant à ce chiffre

S. DAHMANI
Cours C++ 11
Exemple 4 : transformation char-int

S. DAHMANI
Cours C++ 12
Transformation majuscule-minuscule
 Pour transformer un caractère c qui est une
majuscule en la minuscule correspondante, il
suffit de lui ajouter ('a'-'A').
 Pour transformer un caractère c qui est une
minuscule en la majuscule correspondante, il
suffit de lui ajouter ('A'-'a').

S. DAHMANI
Cours C++ 13
Exemple 5 : transformation majuscule-minuscule

S. DAHMANI
Cours C++ 14
Execution

S. DAHMANI
Cours C++ 15
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.

S. DAHMANI
Cours C++ 16
S. DAHMANI
Cours C++ 17
Sur le schéma, on voit cette fois toutes les cases de la mémoire
avec leurs adresses. Notre programme utilise une seule de ces
cases, la 53768, pour y stocker sa variable.

S. DAHMANI
Cours C++ 18
 Le point important ici est que chaque variable
possède une seule adresse et que chaque
adresse correspond à une seule variable.
 L'adresse est donc un deuxième moyen
d'accéder à une variable. On peut atteindre la
case jaune du schéma par deux chemins
différents :
 On peut passer par son nom (l'étiquette) comme
on sait déjà le faire…
 Mais on peut aussi accéder à la variable grâce à
son adresse (son numéro de case). On pourrait
alors dire à l'ordinateur « Affiche moi le contenu
de l'adresse 53768 » ou encore « Additionne les
contenus des adresses 1267 et 91238 ».
S. DAHMANI
Cours C++ 19
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.

S. DAHMANI
Cours C++ 20
Exemple
 #include <iostream>
 using namespace std;
 int main()
 {
 int ageUtilisateur(16);
 cout << "L'adresse est : " <<
&ageUtilisateur << endl;
 //Affichage de l'adresse de la variable
 return 0;
 } S. DAHMANI
Cours C++ 21
Resultat

S. DAHMANI
Cours C++ 22
Déclarer un pointeur

 int *pointeur(0);
 double *pointeurA(0);
 unsigned int *pointeurB(0);
 string *pointeurC(0);
 int const *pointeurE(0);

S. DAHMANI
Cours C++ 23
Stocker une adresse
 int main()
 {
 int ageUtilisateur(16);
 //Une variable de type int
 int *ptr(0);
 //Un pointeur pouvant contenir l'adresse d'un nombre
entier
 ptr = &ageUtilisateur;
 //On met l'adresse de 'ageUtilisateur' dans le pointeur
'ptr„
 return 0;
 }
S. DAHMANI
Cours C++ 24
S. DAHMANI
Cours C++ 25
Afficher l'adresse

 #include <iostream>
 using namespace std;
 int main()
 {
 int ageUtilisateur(16);
 int *ptr(0);
 ptr = &ageUtilisateur;
 cout << "L'adresse de 'ageUtilisateur' est : " << &ageUtilisateur <<
endl;
 cout << "La valeur de pointeur est : " << ptr << endl;
 return 0;
 }

S. DAHMANI
Cours C++ 26
Accéder à la valeur pointée

 int main()
 {
 int ageUtilisateur(16);
 int *ptr(0);
 ptr= &ageUtilisateur;
 cout << "La valeur est : " << *ptr << endl;
 //*ptr affiche la valeur 16
 return 0;
 }

S. DAHMANI
Cours C++ 27
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 .

S. DAHMANI
Cours C++ 28
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;
S. DAHMANI
Cours C++ 29
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;
. pc=&i; erreur
On peut cependant forcer la conversion.
A utiliser avec précaution ....

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

S. DAHMANI
Cours C++ 30
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
S. DAHMANI
Cours C++ 31
Exemple: utilisation de pointeurs

S. DAHMANI
Cours C++ 32
Exemple 2:un autre exemple d'utilisation de
pointeurs

S. DAHMANI
Cours C++ 33
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.
S. DAHMANI
Cours C++ 34
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

S. DAHMANI
Cours C++ 35
Un exemple de tableau
 Déclaration d'un tableau : int a[10]; a est un
tableau de 10 cases.
 Chaque case contient un entier (type int). La
première case s‟appelle a[0]. La deuxième case
s‟appelle a[1] et la dixième case a[9].
 Remarque : la case a[10] n‟existe pas ! Car la
première case possède l'indice 0. Si vous
essayez d'accéder à une case dont l'indice n'est
pas valide, le programme "plantera". Sur chaque
case, on peut effectuer les opérations
habituelles : addition, affectation…etc…
S. DAHMANI
Cours C++ 36
Exemple 1 : utilisation d'un tableau
#include <iostream>
using namespace std;
int main() { int t[10], i;
for(i=0; i<10;i++){
cout<< "Tapez la valeur numero " << i << " : ";
cin >> t[i]; }
for(i=0; i<10;i++) t[i] = t[i]+1;
for(i=0; i<10;i++)
cout<< "La valeur numero " << i <<" est : "<< t[i] <<endl;
System(“pause”);
Return 0;
}
S. DAHMANI
Cours C++ 37
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

S. DAHMANI
Cours C++ 38
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
S. DAHMANI
Cours C++ 39
S. DAHMANI
Cours C++ 40
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

S. DAHMANI
Cours C++ 41
Exercice1

 Écrire un programme qui demande à


l‟utilisateur de saisir 10 entiers stockés dans
un tableau. Le programme doit afficher le
nombre d'entiers supérieurs ou égaux à 10.

S. DAHMANI
Cours C++ 42
Solution :Ex1
 #include <iostream>
 const int N = 10;
 int main() {
 int t[N], i, nb = 0;
 for (i=0; i<N; i++) { std::cout << "Tapez un
entier "; std::cin >> t[i]; }
 for (i=0; i<N; i++) { if(t[i]>=10) { nb++; } }
std::cout << "Le nombre d'entiers supérieurs
ou égaux à 10 est : " << nb << std::endl;
return 0; }
S. DAHMANI
Cours C++ 43
Exercice 2:

 Écrire un programme qui demande à


l‟utilisateur de saisir 10 entiers stockés dans
un tableau ainsi qu‟un entier V. Le
programme doit rechercher si V se trouve
dans le tableau et afficher « V se trouve dans
le tableau » ou « V ne se trouve pas dans le
tableau ».

S. DAHMANI
Cours C++ 44
 #include <iostream>
 const int N=10;
 int main() { int t[N], i, V; bool trouve;
 for (i=0; i<N; i++) { std::cout << "Tapez un entier : ";
std::cin >> t[i]; }
 std::cout << "Tapez la valeur de V : "; std::cin >> V;
 trouve = false; i = 0;
 while (!trouve && i<N) { if (t[i]==V) { trouve=true; } else {
i++; } }
 if (trouve) { std::cout << "La valeur V se trouve dans le
tableau" << std::endl; }
 else { std::cout << "La valeur V ne se trouve pas dans le
tableau" << std::endl; } return 0; }

S. DAHMANI
Cours C++ 45
Exercice 3:
 Écrire un programme qui demande à
l‟utilisateur de saisir 10 entiers stockés dans
un tableau. Le programme doit ensuite
afficher l‟indice du plus grand élément.

S. DAHMANI
Cours C++ 46
3-L'allocation dynamique
La gestion automatique de la mémoire

 Dans notre tout premier chapitre sur les


variables, je vous avais expliqué que, lors de la
déclaration d'une variable, le programme
effectue deux étapes :
 Il demande à l'ordinateur de lui fournir une zone
dans la mémoire. En termes techniques, on
parle d'allocation de la mémoire.
 Il remplit cette case avec la valeur fournie. On
parle alors d'initialisation de la variable.

S. DAHMANI
Cours C++ 47
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.

S. DAHMANI
Cours C++ 48
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

T *p;
p = new T ou T *p = new T
S. DAHMANI
Cours C++ 49
 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.

S. DAHMANI
Cours C++ 50
 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

S. DAHMANI
Cours C++ 51
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;

S. DAHMANI
Cours C++ 52
 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;

S. DAHMANI
Cours C++ 53
Un exemple complet
 #include <iostream>
 using namespace std;
 int main()
 {
 int* pointeur(0);
 pointeur = new int;
 cout << "Quel est votre age ? ";
 cin >> *pointeur;
 //On écrit dans la case mémoire pointée par le pointeur 'pointeur„
 cout << "Vous avez " << *pointeur << " ans." << endl;
 //On utilise à nouveau *pointeur
 delete pointeur; //Ne pas oublier de libérer la mémoire
 pointeur = 0; //Et de faire pointer le pointeur vers rien
 return 0;
 }

S. DAHMANI
Cours C++ 54
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].
S. DAHMANI
Cours C++ 55
Exemple

S. DAHMANI
Cours C++ 56
• 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 :

S. DAHMANI
Cours C++ 57
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.
S. DAHMANI
Cours C++ 58
Exemple de tableau de chaînes:

S. DAHMANI
Cours C++ 59
 #include<iostream>
 using namespace std;
 int main()
 {
 int i ,nbMots;
 char **tabMots;
 cout << "nombre de mot: ? ";
 cin >> nbMots;
 tabMots = new char *[nbMots];
 for(i=0;i<nbMots;i++)
 {
 tabMots[i]=new char;
 cout<<"Mots"<<i+1<<"?:";
 cin>>tabMots[i];
 }
 for (i=0;i<nbMots;i++){cout<<tabMots[i]<<endl;}
 for (i=0;i<nbMots;i++){delete tabMots[i];}
 delete [] tabMots;
 system("pause");
 return 0;
 }
S. DAHMANI
Cours C++ 60
Partager une variable

S. DAHMANI
Cours C++ 61
 #include <iostream>
 #include <string>
 using namespace std;
 int main()
 {
 string reponseA, reponseB, reponseC;
 reponseA = "La peur des jeux de loterie";
 reponseB = "La peur du noir";
 reponseC = "La peur des vendredis treize";
 cout << "Qu'est-ce que la 'kenophobie' ? " << endl; //On pose la
question
 cout << "A) " << reponseA << endl; //Et on affiche les trois
propositions
 cout << "B) " << reponseB << endl;
 cout << "C) " << reponseC << endl;

S. DAHMANI
Cours C++ 62
 char reponse;
 cout << "Votre reponse (A,B ou C) : ";
 cin >> reponse; //On récupère la réponse de l'utilisateur
 string *reponseUtilisateur(0); //Un pointeur qui pointera sur la réponse
choisie
 switch(reponse)
 {
 case 'A':
 reponseUtilisateur = &reponseA; //On déplace le pointeur sur la réponse
choisie
 break;
 case 'B':
 reponseUtilisateur = &reponseB;
 break;
 case 'C':
 reponseUtilisateur = &reponseC;
 break;
 }
 //On peut alors utiliser le pointeur pour afficher la réponse choisie
 cout << "Vous avez choisi la reponse : " << *reponseUtilisateur << endl;
 return 0;
S. DAHMANI
 } Cours C++ 63
Fin

 http://www.exelib.net/langage-
cpp/references-et-pointeurs.html#solution-tab
 http://chamilo2.grenet.fr/inp/main/document/d
ocument.php?curdirpath=%2FTP&cidReq=
 http://www.fresnel.fr/perso/stout/langageC.ht
m

S. DAHMANI
Cours C++ 64

Vous aimerez peut-être aussi