Chap 1 C 2
Chap 1 C 2
Module
Programmation C2
1
noura.ouerdi2@[Link]
Département d’Informatique
A.U. 2023-2024
OBJECTIFS DU MODULE
2
CONNAISSANCES À
ACQUÉRIR
3
PLAN DU COURS
▪ Chapitre 1 : Pointeurs et allocation dynamique de la
mémoire
▪ Chapitre 2: Structures
▪ Définition des types structures :
▪ Définition par type struct
▪ Définition par typedef
▪ Déclaration des variables structures
▪ Accès aux champs d’une structure
▪ Chapitre 3 : Récursivité
▪ Récursivité simple
▪ Récursivité multiple
4
PLAN DU COURS
▪ Chapitre 5 : Tri et recherche
▪ Tri par sélection
▪ Tris à bulle
▪ Tri par fusion
▪ Recherche séquentielle
▪ Recherche dichotomique
▪ Chapitre 6 : Les fichiers
▪ Introduction
▪ Déclaration de fichiers
▪ Fonctions d’ouverture et de fermeture (fopen, fclose)
▪ Fonction de lectures et d’écriture (fread, fwrite)
5
CHAPITRE 1 : POINTEUR ET
GESTION DYNAMIQUE
6
I – Les Pointeurs
7
Introduction
Rappel : Étapes de compilation
Code source programme.c
Editeur de
liens
Programme exécutable
[Link]
8
Introduction
Rappel : Structure d’un programme C
Fichier entête contient ce dont le compilateur a
besoin pour compiler correctement le programme
9
Notion de Variable - RAM
RAM
RAM . int X;
Données
. .
.
Variables
Constantes
. X = 25;
Instructions
. (00011001)2
(19)16 = 0x19
Lectures 0x0004
Affectations
Tests 0x00 0x0003
croissantes
Adresses
Boucles
0x00 0x0002
…
X
Ecritures 0x00 0x0001
0x19 0x0000
10
DONNÉES STATIQUES ET DYNAMIQUES
▪ En langage C un programme comporte deux types
de données :
▪ Statiques ;
▪ Automatiques;
▪ Dynamiques.
11
DONNÉES STATIQUES
▪ Les données statiques occupent un
emplacement parfaitement défini lors de la
compilation. La mémoire allouée est fixe.
▪ Une fois la mémoire allouée, elle ne peut plus
être changée. Par exemple, en langage C si le
programmeur écrit int x[10]; x est un tableau
pouvant stocker une séquence de données du
même type. Il peut stocker dix éléments
entiers. Il ne peut pas stocker plus de dix
éléments.
12
DONNÉES AUTOMATIQUES
▪ Elles, en revanche, n’ont pas une taille
définie a priori.
▪ En effet, elles ne sont créées et détruites qu’au
fur et à mesure de l’exécution du programme.
▪ Elles sont souvent gérées sous forme de ce
que l’on nomme une pile (stack en anglais).
Remarque : Dans la plupart des langages de
programmation compilés, la pile (stack) est
l’endroit où sont stockés les paramètres
d’appel et les variables locales des
fonctions (ces variables sont désallouées
automatiquement)
13
DONNÉES DYNAMIQUES
15
POINTEURS
Exemple 1 :
main()
{ int a,b,c;
printf("Taille d'un entier%d\n",sizeof(int));
printf("Adresse de a %x\n",&a);
printf("Adresse de b %x\n",&b);
printf("Adresse de c %x",&c);
getch(); }
%x pour un affichage en Hexadécimal
16
POINTEURS
17
POINTEURS (SUITE)
18
DÉFINITION D’UN POINTEUR
19
DÉCLARATION D’UN POINTEUR
La syntaxe pour déclarer un pointeur est la suivante :
Type *NomPointeur ;
21
DÉCLARATION D’UN POINTEUR (SUITE)
◼ Dans la déclaration d’un pointeur, le symbole * est associé au nom
de la variable pointeur et non pas au type.
◼ Ainsi, la déclaration :
int *a, b ;
Ne déclare pas deux pointeurs a et b, mais un pointeur a vers un
int et une variable simple b de type int.
◼ Pour déclarer deux pointeurs a et b dans la même ligne, il faut
écrire :
int *a , *b ;
◼ La valeur d’un pointeur donne l’adresse du premier octet parmi
les n octets où la variable est stockée.
22
DÉCLARATION D’UN POINTEUR (SUITE)
◼ Lors du travail avec des pointeurs, nous avons besoin :
- d’un opérateur 'adresse de’ & pour obtenir l'adresse d'une variable.
- d’un opérateur 'contenu de' * pour accéder au contenu d'une
adresse.
◼ Lorsqu’on déclare un pointeur p sur un objet de type T , on ne sait
pas sur quoi il pointe.
◼ Pour initialiser un pointeur de type T, il faut lui affecter l’adresse
d’une variable de même type T.
23
DÉCLARATION D’UN POINTEUR (SUITE)
Exemple 2 :
int *ad ;
int n ;
n = 20 ;
ad = &n ;
*ad = 30;
int *ad ; réserve la variable ad comme étant un “pointeur”
sur des entiers.
n int *ad ;
20 30
n = 20 ;
n = 30
ad = &n ;
ad
*ad=30 ; affecte la valeur 30 à *ad,
c’est à dire n = 30 ;
25
DÉCLARATION D’UN POINTEUR (SUITE)
mémoire int *ad1 , *ad2 ;
1022 n
20 p
int n = 10 ;
ad1 int p = 20 ;
ad1 = &n ;
ad2 = &p ;
ad2
*ad1 = *ad2+2;
26
les instructions 3 et 4 placent respectivement dans ad1 et ad2 les adresses de n et p.
DÉCLARATION D’UN POINTEUR (SUITE)
!
déclarer un pointeur.
int* p ;
int *q ;
int * r ;
Exemple 4 :
main()
{ int a ; int * p ; a = 12 ; p = &a ; *p = 15 ;
printf(‘’ a : %d \n ‘’,a) ; printf(‘’ *p : %d \n’’,*p) ;
getch() ;}
Résultat : a : 15 *p : 15
27
DÉCLARATION D’UN POINTEUR (SUITE)
Attention : int* p, q ;
28
ACCÈS À LA VARIABLE POINTÉE
◼ L’opérateur * permet d’accéder à la valeur de la variable pointée par un
pointeur donné.
◼ Considérons un pointeur p qui pointe vers une variable w de type T.
L’expression *p est équivalente à w.
◼ Donc, on peut manipuler la variable w soit directement par son nom ou soit
indirectement par *p.
◼ En fait, *p est considérée comme une variable de type T et tout ce qui est
applicable sur w, on peut l’appliquer sur *p.
◼ Exemple:
◼ Si un pointeur p pointe sur une variable a, alors toutes les opérations réalisées
sur la variable a (accès direct) peuvent être réalisées sur *p (accès indirect) .
int a = 3 , b , *p ;
p = &a;
b = a – 1; /* est équivalente à b = *p - 1 */
a += 2 ; /* est équivalente à *p += 2 */
++a ; /* est équivalente à ++*p */
a++; /* est équivalente à (*p)++ */
29
ACCÈS À LA VARIABLE POINTÉE
#include <stdio.h>
main(){
int n = 2, m = -4, k;
int *p, *q;
p=&n;
q=&m;
K =*p * *q;
printf("%d \t %d \t %d",*p,*q,k);
(*p)-- ;
(*q)++ ;
printf("%d \t %d \t %d",*p,*q, n);
(*p)+=4 ;
(*q)-=2 ;
printf("%d \t %d \t %d",*p,*q, m);}
Résultat?
2 -4 -8
1 -3 1
5 -5 -5 30
ACCÈS À LA VARIABLE POINTÉE
◼ Remarque : Si un pointeur P pointe sur une variable X, alors
*P peut être utilisé partout où on peut écrire X.
X+=2 équivaut à (*P)+=2
++X équivaut à ++*P
X++ équivaut à (*P)++ // != *P++
31
INITIALISATION D’UN POINTEUR
◼ Toute utilisation d’un pointeur devra être précédée par une initialisation en
utilisant l’opérateur l’opérateur unaire "&" .
◼ A la déclaration d’un pointeur p, on ne sait pas sur quelle zone mémoire il
pointe.
◼ Ces instructions peuvent générer des problèmes :
int *p;
*p = 10; // *p n’a pas de sens, elle n’existe pas
provoque un problème mémoire car le pointeur p n’a pas été initialisé.
Aussi, l’écriture suivante provoque un problème mémoire :
int *p;
p = 200; // ou p = 231564
◼ On ne peut pas le faire, car on ne sait pas si l’adresse 200 (ou l’adresse 231564)
est occupée par une autre variable du programme ou d’un autre programme,
voir un programme système.
◼ Il faut laisser le compilateur choisir les adresses convenables, c’est l’allocation
dynamique.
32
INITIALISATION D’UN POINTEUR
◼ On peut initialiser un pointeur en lui affectant :
▪ L’adresse d’une autre variable :
- Si la variable n’est pas un pointeur on doit utiliser l’opérateur &.
- Exemple :
int *p1; // déclaration d’un pointeur vers un int
int a=14; // supposons que a se trouve à l’adresse 0x352C
p1=&a; // affectation de l’adresse de a au pointeur p1, soit
0x352C
▪ Un autre pointeur déjà initialisé :
- L’affectation d’un pointeur à un autre est possible si les deux pointeurs sont de
même type.
- Si p1 et p2 sont deux pointeurs de type T, alors l’expression p1 = p2; permet
d’affecter le pointeur p2 au pointeur p1.
- Cela a pour effet de faire pointer p1 et p2 vers la même variable (la même
adresse).
- Exemple :
int *p2;
p2 = p1; //affectation de p1 à p2
33
INITIALISATION D’UN POINTEUR
34
INITIALISATION D’UN POINTEUR
◼ Exemple 1 :
35
INITIALISATION D’UN POINTEUR
◼ Exemple 2 :
int *p , a=5 , b=3 ;
p=&a; /* p pointe sur la variable a */
b=*p; /* affecte à la variable b la valeur pointée par p */
*p = 1; /* affecte la valeur 1 à la variable pointée par p */
printf (" %d ", b); /* affiche 5 */
printf (" %d ", *p); /* affiche 1 */
printf (" %d ", a); /* affiche 1 */
a b *p
p=&a 5 3 5
b=*p 5 5 5
*p=1 1 5 1
36
INITIALISATION D’UN POINTEUR
◼ Exemple 3 :
int *p1, *p2; //déclaration de 2 pointeurs vers des entiers
int i = 14; // supposons que i se trouve à l’adresse 0x352C
p1 = &i; // affectation à l’adresse de i à p1 , soit 0x352C
p2 = p1; // affectation de p1 à p2 : p2 contient aussi
l’adresse de i
◼ Pour bien montrer l’intérêt de l’initialisation de tout pointeur, reprenons le
même exemple précédent dans lequel on remplace l’affectation p2 = p1 par
*p2 = *p1. Que va-t-il passer ?
◼ Réponse :
1. p1 est bien initialisé et pointe sur i (*p1=14).
2. Mais p2 n’a pas été initialisé :
▪ p2 désigne une adresse mémoire inconnue.
▪ L’instruction *p2 = *p1 force l’écriture de la valeur *p1=14 dans la case
mémoire pointée par p2, alors que p2 ne pointe sur aucune adresse valide.
Cela pourra entrainer un comportement indéfinie.
▪ Cette écriture est en général sanctionnée par le message d’erreur
37
”Segmentation fault” à l’exécution.
PASSAGE DE L’ADRESSE D’UNE VARIABLE DANS UNE
FONCTION
Nous voulons échanger simplement les valeurs de deux variables, à
l’aide d’une fonction. Voyons l’exemple suivant :
Swap(int a , int b) { int temp;
printf(“Avant l’échange dans la fonction Swap \n”);
printf(“a=%d et b=%d\n “,a,b) ;
temp = a; a=b; b = temp;
printf(“Après l’échange dans la fonction Swap \n”);
printf(“a=%d et b=%d\n “,a,b) ; }
main() { int x=10 , y=15 ;
printf(“Avant l’échange dans le programme principal \n”);
printf(“x=%d et y=%d \n”,x,y); Swap(x,y) ;
printf(“Après l’échange dans le programme principal \n”);
printf(“ x= %d et y=%d \n “,x,y) ; getch() ; } 38
PASSAGE DE L’ADRESSE D’UNE VARIABLE DANS UNE
FONCTION (SUITE)
42
Relation entre pointeurs et tableaux (suite)
▪ Version 1:
▪ main(){
float T[100], *pt;
int i, n;
do{ // test pour que 0 <= n <= 100
printf("Entrez n : \n ");
scanf("%d",&n);
} while(n<0 ||n>100);
pt=T;
for(i=0; i<n; i++){
printf("Entrez T[%d] \n ",i);
scanf("%f", pt+i); // pt + i &T[i]
}
for(i=0;i<n;i++)
43
printf("%f \t",*(pt+i)); } // T[i]
Relation entre pointeurs et tableaux (suite)
▪ Version 2 : Sans utiliser i
main() {
Float T[100], *pt;
int n;
do{ // test pour que 0 <= n <= 100
printf("Entrez n : \n ");
scanf("%d",&n);
} while(n<0 ||n>100);
for(pt=T; pt<T+n; pt++){
printf ("Entrez T[%d] \n ",pt-T); // pour afficher 0,
1,..
scanf("%f", pt); //pt &T[i]
}
for(pt=T; pt<T+n; pt++)
printf (" %f \t",*pt); } 44
Relation entre pointeurs et tableaux (suite)
◼ Exemple 1 :
Quelle est la valeur de la variable s après l’exécution de ce programme :
#include<stdio.h>
main(){
int x[6] = {1, 2, 3, 4, 5, 6}, i, s = 0;
int * p = &x[0]; // ou int *p=x
for(i = 0; i 6; i++){
s + = * (p + i);
} }
Résultat?
◼ Les variables utilisées : x est un tableau de 6 entiers, k et s deux entiers et p est
un pointeur vers un entier. La valeur initiale de s est 0.
◼ Le pointeur p va parcourir le tableau x en utilisant le pointeur p et calcule dans
s la somme des éléments de x par l’instruction :
s = s + *(p + i) 45
Relation entre pointeurs et tableaux (suite)
◼ Exemple 2:
#include <stdio.h>
main(){
int t[8]={-2,6,3,-2,1,9,0,-1};
int *p;
for(p=t; p<t+8; p++)
printf("%d \t", *p);
}
Résultat?
/* cette instruction va afficher : -2 6 3 -2 1 9
0 -1 */
46
Relation entre pointeurs et tableaux (suite)
◼ Exemple 3:
#include <stdio.h>
#define N 10
main(){
int T[N] = {3,6,0,8,97,0,5,6,0,8} ;
int *Deb, *Fin, *Comp;
Deb = &T[0] ;
Fin = &T[N-1];
for(Comp=Deb; Comp <= Fin; Comp++)
printf("%d \n",*Comp);}
Résultat?
// il affiche le tableau T 47
ARITHMÉTIQUE DES POINTEURS
On peut faire des calculs avec les pointeurs, mais les règles sont un
peu différentes. Un pointeur contient une adresse, qui exprime un
décalage, en octets, depuis l’adresse 0.
Exemple :
main() { int n=10, *p=&n;
printf("n est un int, de taille %d octets\n",sizeof(n));
printf("adresse de n : %p \n",p);
printf("adresse suivante : %p\n",++p); getch(); }
1 (++p).
49
ARITHMÉTIQUE DES POINTEURS (SUITE)
50
ARITHMÉTIQUE DES POINTEURS (SUITE)
▪ Autre Exemple:
▪ q=p+1;
▪ printf("valeur de p: %d \n",p);
▪ printf("valeur de q : %d\n",q);
▪ getch(); }
51
ARITHMÉTIQUE DES POINTEURS (SUITE)
▪ Résultat:
52
ARITHMÉTIQUE DES POINTEURS (SUITE)
Dans le cas des tableaux, regardez cet exemple :
main() { int tab[10]; tab[3]=20;
printf("tab[3] vaut %d\n",tab[3]);
printf("tab[3] vaut %d\n",*(tab+3)); getch(); }
La première façon affiche la valeur de tab[3], c’est la façon
classique.
p • a
p+3 •
54
OPÉRATIONS SUR LES POINTEURS
◼ Exemple :
Soit a une variable de type int et p est un pointeur vers a. Sachant que
le type int est codé sur 4 octets et que l’adresse de la variable a est
1030, quel est le contenu du pointeur p + 3 ?
◼ Solution :
▪ Le pointeur p pointe vers a, donc le contenu de p est l’adresse de a ,
c’est-à-dire 1030.
▪ Le pointeur p + 3 pointe vers l’entier qui se trouve 3 fois après celui
qui contient la variable a.
▪ Donc le contenu du pointeur p + 3 est 1030 + 3 * 4 = 1042.
55
OPÉRATIONS SUR LES POINTEURS
◼ Autre exemple :
#include <stdio.h>
main(){
double i = 3;
double *p, *q, *r;
p = &i;
q = p + 1;
r = p + 3 ;
printf("p = %d \t q = %d \t r = %d \n", p, q, r); }
56
SOUSTRACTION D’UN ENTIER À UN POINTEUR
▪
• a
57
SOUSTRACTION D’UN ENTIER À UN POINTEUR
▪
58
SOUSTRACTION D’UN ENTIER À UN POINTEUR
◼ Exemple :
#include <stdio.h>
main(){
int i = -1;
int *p, *q, *r;
p = &i;
q = p - 1;
r = p - 3 ;
printf("p = %d \t q = %d \t r = %d \n",p,q,r);
getch();
}
▪ Il affiche
p=2686788 q=2686784 r=2686776
59
INCRÉMENTATION D’UN POINTEUR
▪
60
INCRÉMENTATION D’UN POINTEUR
◼ Exemple :
▪ La variable a de type int est rangée en mémoire à l’adresse 1000.
Quel est le contenu de chacun des pointeurs suivants :
int * p = &a;
int * q = p++;
int * r = ++q;
▪ Donnez les valeurs des différents pointeurs pour chaque instruction.
▪ Réponse?
▪ Le pointeur p pointe vers a, donc le contenu de p est l’adresse de a,
c’est-à-dire 1000.
▪ q = p++; est équivalente à q = p; p = p + 1; Donc le contenu du
pointeur q est 1000, mais le pointeur p est incrémenté et par suite, le
contenu de p est 1004.
▪ r = ++q; est équivalente à q = q + 1; r = q; Donc le contenu du
pointeur q est 1004, et celui de r est 1004.
▪ La variable a ?? Elle n’est plus pointée par ces pointeurs
61
DÉCRÉMENTATION D’UN POINTEUR
◼ Si p est un pointeur vers une variable a de type T.
L’expression p-- est le pointeur qui pointe vers la
variable de même type que a qui se trouve
immédiatement avant a.
◼ L’expression p-- est équivalente à l’expression
p = p - 1.
62
DÉCRÉMENTATION D’UN POINTEUR
◼ Exemple :
▪ La variable a de type int est rangée en mémoire à l’adresse 1000. Quel est le contenu
de chacun des pointeurs suivants :
int * p = &a;
int * q = p--;
int * r = --q;
Valeurs après exécution?
▪ Le pointeur p pointe vers a, donc le contenu de p est l’adresse de a, c’est-à-dire
1000.
▪ q = p--; est équivalente à q = p; p = p - 1; Donc le contenu du pointeur q est 1000,
mais le pointeur p est décrémenté et par suite, le contenu de p est 996.
▪ r = --q; est équivalente à q = q - 1; r = q; Donc le contenu du pointeur q est 996, et
celui de r est 996.
▪ r = ++q; est équivalente à q = q + 1; r = q; Donc le contenu du pointeur q est 1000,
et celui de r est 1000.
63
DIFFÉRENCE DE DEUX POINTEURS
▪
64
DIFFÉRENCE DE DEUX POINTEURS
▪
65
DIFFÉRENCE DE DEUX POINTEURS
◼ Remarque :
▪ La somme de deux pointeurs n’est pas autorisée.
▪ Produit et division aussi.
▪ ils n’ont aucun sens.
◼ Exemple :
#include <stdio.h>
main() {
int a;
int *p, *q;
p=&a ;
q=p+3;
printf("%d", q-p); /* cette instruction va afficher 3 */
printf("%d", p-q); /* cette instruction va afficher -3 */
}
66
POINTEURS DE TYPE POINTEURS
◼ Puisque les pointeurs sont des variables, et on peut déclarer des
pointeurs qui pointent sur n’importe quel type de variables, alors il
est possible de déclarer des pointeurs qui pointent sur des
pointeurs.
◼ La syntaxe de la déclaration est la suivante :
Type **Nom_pointeur ;
67
POINTEUR SUR UN POINTEUR
main() {
int a = 14 ; int* p = &a ; int** pp = &p ;
printf("a vaut : (%d , %d , %d)\n",a,*p,**pp);
printf("p vaut : (%p , %p , %p)\n",&a,p,*pp);
printf("pp vaut : (%p , %p)\n",&p,pp);
getch();
}
68
POINTEUR SUR UN POINTEUR
L’indirection représentée par deux
étoiles « ** », nous permet de pointer
sur un pointeur.
Pendant l’exécution de ce programme,
vous allez remarquer que sur chaque
ligne d’affichage, on voit plusieurs fois
la même valeur.
69
POINTEUR SUR UN POINTEUR
70
POINTEURS DE TYPE POINTEURS
◼ Exemple : float **p ;
Cette instruction déclare un pointeur qui pointe sur des pointeurs de
type réel. Ce concept est important pour les tableaux à deux
dimensions comme nous le verrons après.
71
POINTEURS DE TYPE POINTEURS
◼ En déclarant un tableau A[N][M] et un pointeur P du même type, on peut
manipuler le tableau A en utilisant le pointeur P en faisant pointer P sur le
premier élément de A (P=&A[0][0]), car la matrice A peut être considérée
comme un vecteur. Ainsi :
P pointe sur A[0][0] et *P désigne A[0][0]
75
ALLOCATION DYNAMIQUE DE LA
MÉMOIRE
76
LA FONCTION MALLOC
▪ La fonction malloc sert à demander au système
78
LA FONCTION MALLOC
▪ L’appel : malloc (50) alloue un emplacement de
50 octets dans le tas et en fournit l’adresse en
retour. Ici, cette dernière est placée dans le
pointeur adr.
79
LA FONCTION MALLOC
▪ b) Second exemple
long * adr ;
.....
adr = malloc(100 * sizeof(long)) ;
.....
for (i=0 ; i<100 ; i++) *(adr+i) = 1 ;
80
LA FONCTION MALLOC
81
LA FONCTION MALLOC
82
EXEMPLE DÉTAILLÉ
83
#include <stdio.h>
▪ #include <stdlib.h>
▪ main() {
▪ *p=*p+2;
▪ i=i-1;
▪ p = &i;
86
◼ Exemple:
#include <stdio.h>
#include <stdlib.h> /* à ajouter */
main() {
int *p,*q, i;
p=malloc(5*sizeof(int)); // on réserve 5 places mémoires pour p
q=malloc(5*sizeof(int)); // on réserve 5 places mémoires pour q
if(p==NULL)
exit(0);
else {
for(i=0;i<5;i++) {
*(p+i)=i+1; /*ou p[i]=i+1; */ initialisation des places
mémoires
printf("%d \t", *(p+i)); } } printf("\n") ;
if(q==NULL)
exit(0);
else {
for (i=0;i<5;i++) {
q[i]=i-1; /* ou *(q+i)=i-1 ; */ initialisation des places
mémoires
printf("%d \t", q[i]); } } }
◼ Après exécution, le programme affiche :
1 2 3 4 5
-1 0 1 2 3
87
REMARQUE SUR LE CAST DE MALLOC
▪ il n'est pas nécessaire de caster le résultat de malloc. Avant le
88
LA FONCTION FREE
▪ L’un des intérêts essentiels de la gestion dynamique
est de pouvoir récupérer des emplacements dont on
n’a plus besoin.
▪ Le rôle de la fonction free est de libérer un
emplacement préalablement alloué.
▪ Voici un exemple qui vous montre comment malloc
peut profiter d’un espace préalablement libéré sur le
tas.
89
LA FONCTION FREE
EXEMPLE D’UTILISATION DE LA FONCTION FREE
#include <stdio.h>
#include <stdlib.h>
main() { char * adr1, * adr2, * adr3 ;
adr1 = malloc (100) ;
printf ("allocation de 100 octets en %p\n", adr1) ;
adr2 = malloc (50) ;
printf ("allocation de 50 octets en %p\n", adr2) ;
free (adr1) ;
printf ("libération de 100 octets en %p\n", adr1) ;
adr3 = malloc (40) ;
printf ("allocation de 40 octets en %p\n", adr3) ; }
90
RÉSULTAT DU PROGRAMME
91
RÉSULTAT DU PROGRAMME
92
AUTRES OUTILS DE GESTION
DYNAMIQUE : CALLOC ET REALLOC
94
LA FONCTION CALLOC
▪ Contrairement à ce qui se passait avec malloc, où le
allouée.
95
LA FONCTION REALLOC
▪ La fonction :
(stdlib.h)
96
LA FONCTION REALLOC
97
LA FONCTION REALLOC
98