introduction à la programmation orientée objet : du c...
Post on 13-Sep-2018
213 Views
Preview:
TRANSCRIPT
Introduction à la programmation orientée objet : du C au C++
Cours N°2
Abdelhak-Djamel SeriaiMaître de conférences
seriai@lirmm.frhttp://www.lirmm.fr/~seriai/
1
Les pointeurs en C
2
Exemple de manipulation de pointeursExemple de manipulation de pointeurs
8
#include<stdio .h>void main ( ){int x = 3; int y = 5;
∗int p; p = &x ; printf(”x = %d\n”, x);∗ p = 4;printf(”x = %d\n”, x); p = &y ;
∗ ∗printf(” p = %d\n”, p); ∗ ∗p = p + 1;printf(”y = %d\n”, y);}
•x est initialisé à 3 •y est initialisé à 5•p = &x fait pointer p sur x
• ∗p et x sont deux écritures différentes de la même variable• printf affiche la valeur de x : x = 3. •∗p = 4 place dans la valeur pointée par p, à savoir x, la valeur 4. •printf affiche x = 4•p = &y fait pointer p sur y
• ∗p est la valeur de la variable pointée y •printf affiche donc *p = 5•∗ ∗p = p + 1 ó y = y + 1 => place dans y la valeur 6
• ∗p pointe sur y, alors p et y sont deux alias pour la même variable
•printf affiche donc y = 6•Ce programme affiche donc : x=3 x=4 *p = 5 y=6
Allocation Dynamique
16
Allocation dynamique de mémoire (2/4)Allocation dynamique de mémoire (2/4)
• En pratique, on utilise la fonction sizeof() pour déterminer la valeur nb octets – Ainsi, pour initialiser un pointeur vers un entier, on écrit :
• Avant l’allocation dynamique et plus généralement avant toute initialisation de p, *p n’a pas de sens – Dans ce cas, toute manipulation de la variable *p générerait en général
une violation mémoire, détectable à l’exécution par le message d’erreur Segmentation fault
18
#include <stdlib.h> int main() {int *p; p = (int*) malloc(sizeof(int)); // allocation dynamique *p = 14;}
Allocation dynamique de mémoire (3/4)Allocation dynamique de mémoire (3/4)• La fonction malloc permet également d’allouer un espace pour plusieurs
objets contigus en mémoire
– L’appel à la fonction malloc a ainsi permis de réserver 8 octets en mémoire (qui permettent de stocker 2 objets de type int) et d’affecter à p l’adresse de cette zone mémoire.
• Le programme affiche 19
#include <stdlib.h> #include <stdio.h> int main() {int *p; p = (int*) malloc(2 * sizeof(int)); //allocation pour 2 int *p = 14; *(p + 1) = 10; printf("p = Ox%lx \t *p = %i \t p+1 = 0x%lx \t *(p+1)=%i\n",(unsigned long) p, *p, (unsigned long)(p+1), *(p+1)); return 0;}
p = Ox8049718 *p = 14 p+1 = 0x804971c *(p+1)=10.
Allocation dynamique de mémoire (4/4)Allocation dynamique de mémoire (4/4)
• La fonction calloc a le même rôle que la fonction malloc mais elle permet de réserver nb-objets objets de nb octets et de les initialiser a` zéro.
• Exemple – Si p est de type int*, – Les deux instructions ci-dessous sont équivalentes
– L’emploi de calloc est simplement plus pratique et plus rapide.
20
calloc (nb-objets,nb octets)
p = (int*) calloc(N,sizeof(int));
p = (int*) malloc (N * sizeof(int)); for (i = 0; i < N; i++) *(p + i) = 0;
Libération dynamique avec la fonction free (1/2)Libération dynamique avec la fonction free (1/2)
• Libérer de la mémoire réservée
– Cette instruction libère le bloc de mémoire désigné par nom-du-pointeur• N’a pas d’effet si le pointeur a la valeur NULL. • A toute instruction de type malloc ou calloc doit être associée une
instruction de type free• Attention :
– La fonction free provoque des erreurs si on essaie de libérer de la mémoire qui n’a pas été allouée par malloc ou calloc
– free ne change pas le contenu du pointeur – Si la mémoire n’est pas libérée à l’aide free, alors elle l’est
automatiquement à la fin du programme• Cependant, cela ne doit pas dispenser de l’utilisation de cette
fonction à exemple des listes chaînées
21
free(nom-du-pointeur );
La valeur NULLLa valeur NULL
• Un pointeur qui ne pointe aucune adresse a la valeur NULL. – Il n’est pas nécessairement initialisé à NULL, – NULL est la valeur que, conventionnellement, on décide de donner à un
pointeur qui ne pointe sur aucune zone mémoire valide.• La fonction malloc retourne NULL si aucune zone mémoire adéquate
n’est trouvée. – Il convient, à chaque malloc, de vérifier si la valeur retournée par
malloc est différente de NULL. • Exemple
23
#include<stdio .h> #include<malloc .h>main()
∗{ int p; ∗p = (int ) malloc (2);
If (p == NULL) exit (0);∗p = 28; printf (”%d\n” , ∗p); free (p);}
Tableaux et pointeurs (2/5)Tableaux et pointeurs (2/5)
• Principe 2 – Le nom d’un tableau, T est l’adresse mémoire du premier élément de ce
tableau– Lorsque l’on passe un tableau en paramètre à un sous-programme, on
mentionne seulement son nom. • T est une variable contenant une adresse mémoire,
– T est par conséquent un pointeur
– Lorsque dans un sous-programme auquel on a passé un tableau en paramètre, on mentionne un indice, par exemple K[i], le compilateur calcule l’adresse du i-ème élément de K pour lire ou écrire à cette adresse.
25
Tableaux et pointeurs (3/5)Tableaux et pointeurs (3/5)
• Principe 3 – Lorsque on déclare un tableau, il est obligatoire de préciser sa taille
• Cela signifie que la taille d’un tableau doit être connue à la compilation.
– Que faire si on ne connait pas la taille d’un tableau à la compilation ?• Deux solutions
– Mauvaise solution : Le surdimensionnement, on donne au tableau une taille très (trop) élevée de sorte qu’aucun débordement ne se produise.
– Bonne solution : préciser la dimension du tableau au moment de l’exécution. Ainsi, lors de la déclaration d’un tableau t, deux zones mémoires seront utilisées.
» Un espace mémoire alloué au stockage de la variable t, c’est à dire la variable qui contient l’adresse mémoire du premier élément du tableau
» Un autre espace mémoire est alloué au stockage des éléments du tableau
26
Tableaux et pointeurs (4/5) Tableaux et pointeurs (4/5)
• L’allocation dynamique d’un tableau– Lors de l’allocation dynamique d’un tableau, il est nécessaire de
déterminer la taille mémoire de la zone à occuper • Pour allouer dynamiquement un tableau de 10 variables de type char
– malloc(10), car un char occupe 1 octet en mémoire. • Pour allouer dynamiquement un tableau de 10 int
– malloc(20), car chaque int occupe 2 octets en mémoire.• La fonction sizeof permet de calculer la place prise en mémoire par la
variable d’un type donné – la valeur sizeof(T) est la taille prise en mémoire par une variable de type
T • Pour allouer dynamiquement un int,
– exécuter l’instruction malloc(sizeof(int)). • Pour allouer dynamiquement un tableau de n variables de type T,
– ∗exécuter l’instruction malloc(n sizeof (T )). » pour allouer un tableau de 10 int, on exécute
∗malloc(10 sizeof (int)). 27
Passage de paramètres par référence (1/3)Passage de paramètres par référence (1/3)
• Exemple illustratif : Permutation de deux variables
– Les variables x et y ne sont que des copies de a et b• Cette permutation n’a aucun effet sur a et b.
29
#include<stdio .h>void echange ( int x , int y) { int t = x;x=y; y=t;}
void main ( ){ int a = 1; int b = 2; printf(”a = %d, b = %d\n”, a, b); echange(a, b); printf(”a = %d, b = %d\n”, a, b);}
Passage de paramètres par référence (2/3)Passage de paramètres par référence (2/3)
• ∗Pour le compilateur, p est la variable pointée par p, cela signifie que l’on ∗peut, utiliser indifféremment p ou x
– nomSousProgramme(. . . , x, . . .) passe en paramètre la valeur de x– nomSousProgramme(. . . , &x, . . .) passe en paramètre la variable x par
référence. • passe en paramètre l’adresse de x, • c’est un moyen de retrouver la variable x depuis le sous- programme
et de modifier sa valeur.– Par exemple, l’instruction scanf(”%d”,&x) permet de placer une
valeur saisie par l’utilisateur dans x,
• Utilisation *T comme type des de variable pour passer l’adresse mémoire d’une variable de type T– ∗int , un pointeur sur int
30
Passage de paramètres par référence (3/3)Passage de paramètres par référence (3/3)• Exemple
– x et y ne sont pas des int, mais des pointeurs sur int. • De ce fait le passage en paramètre des deux adresses &a et &b fait
pointer x sur a et y sur b. – ∗ ∗Donc x est un alias de a et y est un alias de b (pas de copies) – Les valeurs de a et b sont échangées
31
∗ ∗void echange (int x, int y){
∗int t = x; ∗ ∗x = y;∗y=t; }
void main ( ){ int a = 1;int b = 2; printf(”a = %d, b = %d\n”, a, b); echange(&a, &b); printf(”a = %d, b = %d\n”, a, b);}
top related