38
Notions de pointeurs en C Sujets Notions de base sur les pointeurs Pointeurs et Tableaux (matrices) Arithmétiques sur les pointeurs Chaînes de caractères Tableaux à deux dimensions Tableaux de pointeurs Allocation de mémoire Références: http://www.cplusplus.com/doc/tutorial/pointers.html http://www.cs.cf.ac.uk/Dave/C/node10.html http://pweb.netcom.com/~tjensen/ptr/pointers.htm http://www.commentcamarche.net/c/cpoint.php3 http://www.iu.hio.no/~mark/CTutorial/CTutorial.html SIF-1053 Architecture des ordinateurs

Notions de pointeurs en C Sujets Notions de base sur les pointeurs Pointeurs et Tableaux (matrices) Arithmétiques sur les pointeurs Chaînes de caractères

Embed Size (px)

Citation preview

Page 1: Notions de pointeurs en C Sujets Notions de base sur les pointeurs Pointeurs et Tableaux (matrices) Arithmétiques sur les pointeurs Chaînes de caractères

Notions de pointeurs en C Sujets

• Notions de base sur les pointeurs• Pointeurs et Tableaux (matrices)• Arithmétiques sur les pointeurs• Chaînes de caractères• Tableaux à deux dimensions• Tableaux de pointeurs• Allocation de mémoire

Références:http://www.cplusplus.com/doc/tutorial/pointers.htmlhttp://www.cs.cf.ac.uk/Dave/C/node10.htmlhttp://pweb.netcom.com/~tjensen/ptr/pointers.htmhttp://www.commentcamarche.net/c/cpoint.php3 http://www.iu.hio.no/~mark/CTutorial/CTutorial.html

SIF-1053Architecture des ordinateurs

Page 2: Notions de pointeurs en C Sujets Notions de base sur les pointeurs Pointeurs et Tableaux (matrices) Arithmétiques sur les pointeurs Chaînes de caractères

Notions de base des pointeurs• Si nous voulons permuter le contenu de deux variables

entières x et y, nous permuterons ces variables à l’aide d’une fonction "swap(x,y)" qui permet la permutation des variables x et y (les paramètres).

• La version suivante de cette fonction ne fonctionne pas car même si on modifie x et y, les nouvelles valeurs permutées ne sont pas retransmises à la fin de la fonction:

void swap(int x, int y){

int temp;temp=x;x=y;y=temp;

}

Page 3: Notions de pointeurs en C Sujets Notions de base sur les pointeurs Pointeurs et Tableaux (matrices) Arithmétiques sur les pointeurs Chaînes de caractères

Notions de base des pointeurs• Version fonctionnelle:

void swap(int *px, int *py)

{

int temp;

temp=*px;

*px=*py;

*py=temp;

}

• Appel à la procédure swap():

int x=3, y=5;

swap(&x,&y); // &x: & retourne l'adresse de la variable x// x=5 et y=3 au retour du swaP()

Page 4: Notions de pointeurs en C Sujets Notions de base sur les pointeurs Pointeurs et Tableaux (matrices) Arithmétiques sur les pointeurs Chaînes de caractères

Notions de base des pointeurs• La plupart des langages de programmation offrent la

possibilité d'accéder aux données dans la mémoire de l'ordinateur à l'aide de pointeurs, Un pointeur est une variable affectée à la valeur d’un adresse.

• En C, les pointeurs jouent un rôle primordial dans la définition de fonctions• Sachant que le passage des paramètres en C se fait toujours par valeur,

• Les pointeurs permettent de passer une référence sur un objet à une fonction appelée.

• Le pointeur permet donc de changer le contenu de variables déclarées dans d'autres fonctions. Ainsi le traitement de tableaux et de chaînes de caractères dans des fonctions serait impossible sans l'utilisation de pointeurs.

Page 5: Notions de pointeurs en C Sujets Notions de base sur les pointeurs Pointeurs et Tableaux (matrices) Arithmétiques sur les pointeurs Chaînes de caractères

Notions de base des pointeurs• Modes d’adressage

• Adressage direct :

– Dans la programmation, nous utilisons des variables pour stocker des informations.

– La valeur d'une variable se trouve à un endroit spécifique dans la mémoire interne (RAM) de l'ordinateur.

– Le nom de la variable nous permet alors d'accéder directement à cette valeur.

– Donc l’adressage direct permet l’accès au contenu d'une variable par le nom de la variable.

• Adressage indirect :

– Accès au contenu d'une variable, en passant par un pointeur qui contient l'adresse de la variable.

– Donc l’accès à une valeur d’une variable se fait par l’accès préalable au contenu d’un pointeur.

Page 6: Notions de pointeurs en C Sujets Notions de base sur les pointeurs Pointeurs et Tableaux (matrices) Arithmétiques sur les pointeurs Chaînes de caractères

Notions de base des pointeurs• Pointeur

• Un pointeur est une variable qui contient l'adresse d'une autre variable.

• En langage C, chaque pointeur est limité à un type de données. Il peut contenir l'adresse d'une variable simple de ce type ou l'adresse d'une composante d'un tableau de ce type.

• Si un pointeur P contient l'adresse d'une variable A, on dit que 'P pointe sur A'.

• Un pointeur est une variable qui peut 'pointer' sur différentes adresses. Le pointeur pouvant être affecté à différentes adresses.

• Le nom d'une variable reste quant à lui toujours lié à la même adresse en RAM.

Page 7: Notions de pointeurs en C Sujets Notions de base sur les pointeurs Pointeurs et Tableaux (matrices) Arithmétiques sur les pointeurs Chaînes de caractères

Notions de base des pointeurs• Opérateurs sur les pointeurs

• &<var>: opérateur unaire qui retourne l’adresse de la variable var.

int N;

printf("Entrez un nombre entier : ");

scanf("%d", &N); // scanf() prend une adresse comme deuxième argument

• *<p>: opérateur unaire qui retourne le contenu pointer par p un pointeur.

int A=10, B;

int *P;

P = &A;

B = *P;

*P = 20;

10

&A

10A B

P

20

1

2

3

1

2A 3

Page 8: Notions de pointeurs en C Sujets Notions de base sur les pointeurs Pointeurs et Tableaux (matrices) Arithmétiques sur les pointeurs Chaînes de caractères

Notions de base des pointeurs• Déclaration des pointeurs

• <Type> *<NomPointeur> : déclare un pointeur <NomPointeur> qui être affecté des adresses de variables du type <Type>

• Une déclaration comme:

int *P ;

• Le pointeur P est du type int *, donc P est un pointeur sur des objets int

• P contient donc l'adresse d‘objet de type int

• Lors de la déclaration d'un pointeur en C, ce pointeur est lié explicitement à un type de données.

• Donc la variable pointeur P déclarée comme pointeur sur des int ne peut pas recevoir l'adresse d'une variable d'un autre type que int.

Page 9: Notions de pointeurs en C Sujets Notions de base sur les pointeurs Pointeurs et Tableaux (matrices) Arithmétiques sur les pointeurs Chaînes de caractères

Notions de base des pointeurs• Opérations sur les pointeurs

• Les opérateurs * et & ont la même priorité que les autres opérateurs unaires (la négation !, l'incrémentation ++, la décrémentation --).

• Dans une même expression, les opérateurs unaires *, &, !, ++, -- sont évalués de droite à gauche.

• Si un pointeur P pointe sur une variable X, alors *P peut être utilisé partout où on peut écrire explicitement X.

• Si nous avons:

P = &X;

Y = X+1 // Y = *P + 1;

X = X+10 // *P = *P + 10;

X += 2 // *P +=2;

++X // ++(*P); ou ++*P;

X++ // (*P)++

Page 10: Notions de pointeurs en C Sujets Notions de base sur les pointeurs Pointeurs et Tableaux (matrices) Arithmétiques sur les pointeurs Chaînes de caractères

Notions de base des pointeurs• Valeur initiales

• La valeur numérique 0 (zéro, NULL) est utilisée pour indiquer qu'un pointeur ne pointe 'nulle part‘, sur rien.

int *P ;P = 0 ;

• Les pointeurs sont aussi des variables et peuvent être utilisés comme telles. Soit P1 et P2 deux pointeurs sur des int, alors l'affectation

P1 = P2;copie le contenu de P2 vers P1. P1 pointe alors sur le même objet que P2.

Après les instructions suivantes :int A=20, B; // variable int . &A adresse de Aint *P ; // P est un pointeur sur des intP = &A ;B = *P; // Contenu de A affecte a B

Page 11: Notions de pointeurs en C Sujets Notions de base sur les pointeurs Pointeurs et Tableaux (matrices) Arithmétiques sur les pointeurs Chaînes de caractères

Notions de base des pointeurs• Exercisemain(){

int A = 1, B = 2, C = 3;int *P1, *P2;P1=&A; // P1 pointe sur AP2=&C; // P2 pointe sur C*P1=(*P2)++; // A = 3 C = 4P1=P2; // P1 pointe sur CP2=&B; // P2 pointe sur B*P1-=*P2; // C = 2++*P2; // B = 3*P1*=*P2; // C = 6A=++*P2**P1; // A = 24P1=&A; // P1 pointe sur A*P2=*P1/=*P2; // B = 6return 0;

}

Page 12: Notions de pointeurs en C Sujets Notions de base sur les pointeurs Pointeurs et Tableaux (matrices) Arithmétiques sur les pointeurs Chaînes de caractères

Pointeurs et tableaux• int tableau[100];• &tableau[0] et tableau sont une seule et même adresse.

• Donc le nom d'un tableau est un pointeur constant sur le premier élément du tableau.

int A[10], B;

int *P ;

P = A ; // P pointe sur A[0], P = &A[0]; equivalent

B = *(P+1); // P+1 pointe sur le contenu de A[1]

B = *(P+2); // P+2 pointe sur le contenu de A[2]

...

B= *(P+i); // P+i pointe sur le contenu de A[i]

Page 13: Notions de pointeurs en C Sujets Notions de base sur les pointeurs Pointeurs et Tableaux (matrices) Arithmétiques sur les pointeurs Chaînes de caractères

Pointeurs et tableaux

float A[20],

float X ;

float *P ;

P = A ; // P pointe sur l’element A[0]

X = *(P+9) ; // P+9 pointe sur l’element A[9]

• A représente l'adresse de l’élément A[0],

• *(A+1) pointe sur le contenu de A[1]

• *(A+2) pointe sur le contenu de A[2]

...

• *(A+i) pointe sur le contenu de A[i]

…………………

A[0]*(A) A[19]

*(A+19)

Page 14: Notions de pointeurs en C Sujets Notions de base sur les pointeurs Pointeurs et Tableaux (matrices) Arithmétiques sur les pointeurs Chaînes de caractères

Pointeurs et tableaux

• Il existe une différence fondamentale entre une variable pointeur et le nom d'un tableau :

– Un pointeur est une variable, sa valeur peut alors changée, des opérations arithmétiques sur ces pointeurs peuvent être effectuées, comme l’affectation P = A ou des incréments P++ ou toutes autres opérations arithmétiques.

– Le nom associé à un tableau est une constante, donc des opérations arithmétiques comme A = P ou A++ sont illégales.

Page 15: Notions de pointeurs en C Sujets Notions de base sur les pointeurs Pointeurs et Tableaux (matrices) Arithmétiques sur les pointeurs Chaînes de caractères

Pointeurs et tableaux• Exemple tableau VS pointeurmain()

{

int T[10] = {-3, 4, 0, -7, 3, 8, 0, -1, 4, -9};

int POS[10]; // int * Tptr, *Pptr;

int I,J; /* indices courants dans T et POS */

// Tptr = T; Pptr = POS;

for (J=0,I=0; I<10; I++)

if (T[I]>0) // (*(Tptr+I) > 0)

{

POS[J] = T[I]; // *(Pptr+J) = *(Tptr+I)

J++;

}

return 0;

}

Page 16: Notions de pointeurs en C Sujets Notions de base sur les pointeurs Pointeurs et Tableaux (matrices) Arithmétiques sur les pointeurs Chaînes de caractères

Arithmétiques sur les pointeurs• Affectation d’un pointeur

• Soient P1 et P2 deux pointeurs sur le même type de données, alors l'instruction

P1 = P2 ;

• fait pointer P1 sur le même objet que P2.

• Addition et soustraction d’une valeur entière• Si le pointeur P pointe sur l'élément A[i] d'un tableau, alors P+n pointe sur

A[i+n] et P-n pointe sur A[i-n].

• n correspond au nombre d’emplacements du type de donnée pointé qu’il faut se déplacer à partir de P pour atteindre l’emplacement recherché (P+n).

• Ce déplacement (décalage) correspond à un saut de n*sizeof(type de donnée) octets dans la mémoire RAM.

• Si P pointe sur des objets float, P+4 pointe alors sur le cinquième élément de type float, donc 16 octets à partir du début du vecteur de float pointé par P.

Page 17: Notions de pointeurs en C Sujets Notions de base sur les pointeurs Pointeurs et Tableaux (matrices) Arithmétiques sur les pointeurs Chaînes de caractères

Arithmétiques sur les pointeurs• Incrément/Décrément d’un pointeur

• Si P pointe sur l'élément A[i] d'un tableau, alors après l'instruction :

– P = &A[i];

– P++ ; // P pointe sur A[i+1]

– P = &A[i];

– P+= n ; // P pointe sur A[i+n]

– P = &A[i];

– P-- ; // P pointe sur A[i-1]

– P = &A[i];– P-= n ; // P pointe sur A[i-n]

Page 18: Notions de pointeurs en C Sujets Notions de base sur les pointeurs Pointeurs et Tableaux (matrices) Arithmétiques sur les pointeurs Chaînes de caractères

Arithmétiques sur les pointeurs• Rappels importants:

• L'addition, la soustraction, l'incrémentation et la décrémentation sur les pointeurs sont seulement définies à l'intérieur d'un tableau. Si l'adresse formée par le pointeur et l'indice sort du domaine du tableau, alors le résultat n'est pas défini et peut causer des erreurs d’accès mémoire difficiles à détecter.

• Ces opérations arithmétiques sont valables également pour les pointeurs qui pointent vers des variables indépendantes, i.e., ne faisant pas partie d’un tableau. À titre d’exemple, si P pointe sur un élément de type quelconque, alors P+1 pointe sur l’octet qui suit immédiatement cet élément. Exemple : si P pointe sur un short int alors P+1 sera égale à l’adresse référencée par P plus 2 (puisque la taille d’un short int est 2 octets).

Page 19: Notions de pointeurs en C Sujets Notions de base sur les pointeurs Pointeurs et Tableaux (matrices) Arithmétiques sur les pointeurs Chaînes de caractères

Arithmétiques sur les pointeurs• Exemples d’utilisations d’opérations arithmétiques

int A[10] ;

int *P ;

P = A+9 ; // P pointe sur le dixieme element de A

P = A+11 ; // P pointe au-dela du vecteur A de 8 octets

P = A-1 ; // P pointe 4 octets avant le debut de A

Page 20: Notions de pointeurs en C Sujets Notions de base sur les pointeurs Pointeurs et Tableaux (matrices) Arithmétiques sur les pointeurs Chaînes de caractères

Arithmétiques sur les pointeurs• Comparaisons de pointeurs (opérateurs relationnels)

• On peut comparer deux pointeurs par <, >, <=, >=, ==, !=.

• La comparaison de deux pointeurs qui pointent dans le même tableau est équivalente à la comparaison des indices correspondants. (Si les pointeurs ne pointent pas dans le même tableau, alors le résultat est donné par leurs positions relatives dans la mémoire).

Page 21: Notions de pointeurs en C Sujets Notions de base sur les pointeurs Pointeurs et Tableaux (matrices) Arithmétiques sur les pointeurs Chaînes de caractères

Arithmétiques sur les pointeurs• Autre exempleint A[] = {12, 23, 34, 45, 56, 67, 78, 89, 90};

int *P, *P2, B;

P = A;

B = *P+2; // B = 14 = A[0] + 2

B = *(P+2); // B = 36 = A[2] + 2

P2 = &P+1; // P2 pointe sur A[1]

P2 = &A[4]-3; // P2 pointe sur A[1]

P2 = A+3 ; // P2 pointe sur A[3]

B = &A[7]-P; // B = 7

P2 = P+(*P-10) ; // P2 pointe sur A[2]

B = *(P+*(P+8)-A[7]); // B = 23;

Page 22: Notions de pointeurs en C Sujets Notions de base sur les pointeurs Pointeurs et Tableaux (matrices) Arithmétiques sur les pointeurs Chaînes de caractères

Pointeurs (chaînes de caractères)• Initialisation de pointeur sur des chaînes de caractères• Une chaîne de caractères est stockée dans un tableau linéaire de "char". La chaîne de caractères est complétée par le caractère NULL, le zéro binaire ('\0').

char x[]="abcd"; // x est un tableau de 5 caractères, // x[4]=='\0' et aussi x[4]==0

• Un pointeur de char peut être initialisé lors de sa déclaration si on lui affecte l'adresse d'une chaîne de caractères constante :

char *B = "PRO1027" ;

Page 23: Notions de pointeurs en C Sujets Notions de base sur les pointeurs Pointeurs et Tableaux (matrices) Arithmétiques sur les pointeurs Chaînes de caractères

Pointeurs (chaînes de caractères)• Initialisation de pointeur sur des chaînes de caractères

• Il existe une différence importante entre les deux déclarations :

char A[] = "PRO1027"; /* un tableau */

char *B = "PRO1027"; /* un pointeur */

• A est un tableau qui a exactement la grandeur pour contenir la chaîne de caractères et le caractère de fin '\0'. Les caractères de la chaîne peuvent être changés, mais le nom A va toujours pointer sur la même adresse en mémoire.

• B est un pointeur qui pointe sur une chaîne de caractères constante stockée quelque part en mémoire. Le pointeur peut être modifié et pointer sur autre chose. La chaîne constante peut être lue, copiée ou affichée, mais pas modifiée.

Page 24: Notions de pointeurs en C Sujets Notions de base sur les pointeurs Pointeurs et Tableaux (matrices) Arithmétiques sur les pointeurs Chaînes de caractères

Pointeurs (chaînes de caractères)• Initialisation de pointeur sur des chaînes de caractères

char *A = "Chaîne courte" ;

char *B = "Chaîne plus longue";

A = B; // A pointe sur la meme chaine que B

• Les tableaux de caractères permettront de déclarer des chaînes de caractères que nous voulons modifier.

• Les pointeurs de char seront utilisés pour manipuler des chaînes de caractères constantes (dont le contenu ne change pas).

Page 25: Notions de pointeurs en C Sujets Notions de base sur les pointeurs Pointeurs et Tableaux (matrices) Arithmétiques sur les pointeurs Chaînes de caractères

Tableaux à deux dimensions• Un tableau M à deux dimensions peut être définis:

int M[4][10] = { { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9},

{10,11,12,13,14,15,16,17,18,19},

{20,21,22,23,24,25,26,27,28,29},

{30,31,32,33,34,35,36,37,38,39} };

• Le nom du tableau M représente l'adresse du premier élément du tableau et pointe sur le tableau M[0] qui a la valeur {0,1,2,3,4,5,6,7,8,9}. M[0] pointe sur la rangée 0.

• L'expression (M+1) est l'adresse du deuxième élément du tableau M et pointe sur M[1] qui a la valeur {10,11,12,13,14,15,16,17,18,19}. M[1] pointe sur la rangée 1.

• L'arithmétique des pointeurs qui respecte automatiquement les dimensions des éléments conclut logiquement que M+i désigne l'adresse du tableau M[i].

Page 26: Notions de pointeurs en C Sujets Notions de base sur les pointeurs Pointeurs et Tableaux (matrices) Arithmétiques sur les pointeurs Chaînes de caractères

Tableaux à deux dimensions• Exemple pointeur VS tableau 2D

int M[4][10] = { { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9},

{10,11,12,13,14,15,16,17,18,19},

{20,21,22,23,24,25,26,27,28,29},

{30,31,32,33,34,35,36,37,38,39}};

int *P, B;

P = (int *)M; /* conversion forcée */

B = *(P+(2*10) + 2); // B = M[2][2]

• Sachant que M est stockée ligne par ligne, il est maintenant possible traiter M à l'aide du pointeur P comme un tableau unidimensionnel de dimension 4*10.

Page 27: Notions de pointeurs en C Sujets Notions de base sur les pointeurs Pointeurs et Tableaux (matrices) Arithmétiques sur les pointeurs Chaînes de caractères

Tableaux à deux dimensions• Exemple pointeur VS tableau 2D ( des éléments de M)int M[4][10] = { { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9},

{10,11,12,13,14,15,16,17,18,19},

{20,21,22,23,24,25,26,27,28,29},

{30,31,32,33,34,35,36,37,38,39}};

int *P, som=0;

P = (int *)M;

for(int i=0;i<4;i++)

for(int j=0;j<10;j++)

som += M[i][j]; // P[i*10+j] ou *(P+(i*10)+j)

Page 28: Notions de pointeurs en C Sujets Notions de base sur les pointeurs Pointeurs et Tableaux (matrices) Arithmétiques sur les pointeurs Chaînes de caractères

Tableaux à deux dimensions• Pour référencer un tableau 2D à l'aide de pointeurs, nous avons besoin de quatre données :

• L'adresse du premier élément du tableau converti dans le type correspondant aux éléments du tableau

• La longueur d'une ligne réservée en mémoire

• Le nombre d'éléments effectivement utilisés dans une ligne

• Le nombre de lignes effectivement utilisées

Page 29: Notions de pointeurs en C Sujets Notions de base sur les pointeurs Pointeurs et Tableaux (matrices) Arithmétiques sur les pointeurs Chaînes de caractères

Tableaux de pointeurs• Déclaration:

<Type> *<NomTableau>[<N>]

déclare un tableau <NomTableau> de <N> pointeurs sur des données de type <Type>.

double *A[10];

déclare un tableau de 10 pointeurs sur des objets de type double dont les adresses et les valeurs ne sont pas encore définies.

• Les tableaux de pointeurs sont souvent utilisés pour mémoriser de façon économique des chaînes de caractères de différentes longueurs. Ex: Le tableaux char *argv[] passé en argument à la fonction main() d’un programme C.

Page 30: Notions de pointeurs en C Sujets Notions de base sur les pointeurs Pointeurs et Tableaux (matrices) Arithmétiques sur les pointeurs Chaînes de caractères

Tableaux de pointeurs• Nous pouvons initialiser les pointeurs d'un tableau sur char par les adresses de chaînes de caractères constantes.

char *MOIS[] = {"janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre"};

déclare un tableau MOIS[] de 12 pointeurs de char. Chacun des pointeurs est initialisé avec l'adresse de l'une des 12 chaînes de caractères.

On peut afficher ces 12 chaînes de caractères en fournissant les adresses contenues dans le tableau MOIS aux fonction d’affichage printf() ou puts() :

int i;

for (i=0; i<12; i++)

printf("%s\n", MOIS[i]) ; // puts(MOIS[i])

Page 31: Notions de pointeurs en C Sujets Notions de base sur les pointeurs Pointeurs et Tableaux (matrices) Arithmétiques sur les pointeurs Chaînes de caractères

Tableaux de pointeurs• Comme MOIS[i] est un pointeur de char, on peut afficher les premières lettres des mois en utilisant l'opérateur * 'contenu de' :

int i;

for (i=0; i<12; i++) printf("%c\n", *MOIS[i]);

• L'expression MOIS[i]+j correspond à la jième lettre de la iième chaîne.

int i;

for (i=0; i<12; i++) printf("%c\n",*(MOIS[i]+2));

Page 32: Notions de pointeurs en C Sujets Notions de base sur les pointeurs Pointeurs et Tableaux (matrices) Arithmétiques sur les pointeurs Chaînes de caractères

Tableaux de pointeurs• Formatage des sorties avec printf()

Page 33: Notions de pointeurs en C Sujets Notions de base sur les pointeurs Pointeurs et Tableaux (matrices) Arithmétiques sur les pointeurs Chaînes de caractères

Tableaux de pointeurs• Formatage des sorties avec printf()

Page 34: Notions de pointeurs en C Sujets Notions de base sur les pointeurs Pointeurs et Tableaux (matrices) Arithmétiques sur les pointeurs Chaînes de caractères

Tableaux de pointeurs• Formatage des sorties avec printf()

Page 35: Notions de pointeurs en C Sujets Notions de base sur les pointeurs Pointeurs et Tableaux (matrices) Arithmétiques sur les pointeurs Chaînes de caractères

Allocation dynamique • Lorsque nous ne connaissons pas d’avance la dimension des tableaux que nous devons utiliser dans notre application, Nous devons trouver des moyens pour réserver et libérer de la mémoire au fur et à mesure que nous en avons besoin. Nous parlons alors de l'allocation dynamique de la mémoire.

• Déclaration statique de données• Chaque variable dans un programme utilise un certain nombre d'octets en mémoire.

• Les exemples présentés utilisaient un mode de réservation de mémoire automatique appliquée lors des déclarations des données.

• Dans tous ces cas, le nombre d'octets à réserver était déjà connu pendant la compilation. Ce qui correspond à la déclaration statique des variables.

float A, B, C; // 3 X 4 octets

short D[10][20]; // 10 X 20 X 2 octets

char E[] = {"PRO1027"}; // 8 octets

char F[][10] = {"un", "deux", "trois", "quatre"}; // 4 X 10 octets

Page 36: Notions de pointeurs en C Sujets Notions de base sur les pointeurs Pointeurs et Tableaux (matrices) Arithmétiques sur les pointeurs Chaînes de caractères

Allocation dynamique • Déclaration de pointeurs

double *G ; // machine 32 bits, 4 octets char *H ; // machine 32 bits, 4 octetsfloat *I[10] ; // machine 32 bits, 10 X 4 octets

• La fonction malloc() de la bibliothèque <stdlib.h> nous aide à localiser et à réserver de la mémoire au cours d'un programme. • malloc( <N> ) : retourne l'adresse d'un bloc en mémoire de <N> octets libres ou la valeur zéro s'il n'y a pas assez de mémoire.

• Supposons que nous avons besoin d'un bloc de mémoire pour une image de niveaux de gris (0..255) de 1024X1024 unsigned char.

unsigned char *img;

img = malloc(1024*1024) ; // retourne un bloc de 1024X1024 octets• Si nous voulons réserver de la mémoire pour des données d'un type dont la grandeur varie d'une machine à l'autre, nous avons besoin de la grandeur effective d'une donnée de ce type. • L'opérateur sizeof() nous aide alors à préserver la portabilité du programme.

Page 37: Notions de pointeurs en C Sujets Notions de base sur les pointeurs Pointeurs et Tableaux (matrices) Arithmétiques sur les pointeurs Chaînes de caractères

Allocation dynamique sizeof <var> fournit la grandeur de la variable <var>

sizeof <const> fournit la grandeur de la constante <const>

sizeof (<type>) fournit la grandeur pour un objet du type <type>

• Exemples:

short A[10];

char B[5][10];

printf(“\n valeur retourne = %d”,sizeof(A); // 10 X 2

printf(“\n valeur retourne = %d”,sizeof(B); // 5 X 10 X 1

printf(“\n valeur retourne = %d”,sizeof(“PRO1027" ); // 8 printf(“\n valeur retourne = %d”,sizeof(float ); // 4

printf(“\n valeur retourne = %d”,sizeof(double ); // 8

Page 38: Notions de pointeurs en C Sujets Notions de base sur les pointeurs Pointeurs et Tableaux (matrices) Arithmétiques sur les pointeurs Chaînes de caractères

Allocation dynamique • Libération de la mémoire

• Quand un bloc de mémoire que nous avons réservé à l'aide de malloc() n’est plus utilisé, nous pouvons alors le libérer à l'aide de la fonction free() de la bibliothèque <stdlib.h>.

free( <Pointeur> )

• Cette fonction libère le bloc de mémoire désigné par le pointeur <Pointeur>.

• La fonction free() peut aboutir à un désastre si on essaie de libérer de la mémoire qui n'a pas été allouée par malloc().

• La fonction free() ne change pas la valeur (adresse) du pointeur; il est donc conseillé d'affecter la valeur zéro au pointeur immédiatement après avoir libéré le bloc de mémoire qui y était attaché.

• Si nous ne libérons pas explicitement la mémoire à l'aide de la fonction free(), alors elle est libérée automatiquement à la fin du programme.

• MAIS entre temps, un programme qui ne libère pas sa mémoire inutilisée peut occasionner des fuites de mémoire (memory leaks).