cours pointeurs

Upload: oussama-hadj-ali

Post on 07-Apr-2018

217 views

Category:

Documents


0 download

TRANSCRIPT

  • 8/6/2019 cours pointeurs

    1/15

    Les Pointeurs Environnements de Dveloppement (Langage C)

    CH APITRE IX

    Les Point eur s

    La plupart des langages de programmation offrent la possibilit d'accder aux donnes dans la

    mmoire de l'ordinateur l'aide de pointeurs, c'est--dire l'aide de variables auxquelles on

    peut attribuer lesadressesd'autres variables.

    En C, les pointeurs jouent un rle primordial dans la dfinition de fonctions: comme le

    passage des paramtres en C se fait toujours par la valeur, les pointeurs sont le seul moyen dechanger le contenu de variables dclares dans d'autres fonctions. Ainsi le traitement de

    tableaux et de chanes de caractres dans des fonctions serait impossible sans l'utilisation depointeurs (voir Chapitre 9).

    En outre, les pointeurs nous permettent d'crire des programmes plus compacts et plus

    efficients et fournissent souvent la seule solution raisonnable un problme. Ainsi, la majorit

    des applications crites en C profitent extensivement des pointeurs.

    9.1. Adressage de variablesAvant de parler de pointeurs, on va prsenter brivement les deux principaux modesd'adressage de variables.

    9.1.1. Adressage directDans la programmation, nous utilisons des variables pour stocker des informations. La valeur

    d'une variable se trouve un endroit spcifique dans la mmoire interne de l'ordinateur.

    Laccs au contenu ou la valeur d'une variable se fait alors par son nom. Cest ce quonappelle adressage direct.

    Exemple

    9.1.2. Adressage indirectSi on ne veut pas ou on ne peut pas utiliser le nom d'une variable A, on peut copier l'adresse

    de cette variable dans une variable spciale P, appele pointeur. Ensuite, on peut retrouver

    l'information de la variable A en passant par le pointeur P.

    Ainsi, laccs au contenu d'une variable, en passant par un pointeur qui contient l'adresse de la

    variable sappelle adressage indirect.

  • 8/6/2019 cours pointeurs

    2/15

    Les Pointeurs Environnements de Dveloppement (Langage C)

    Exemple

    Soit A une variable contenant la valeur 10 et P un pointeur qui contient l'adresse de A. Enmmoire, A et P peuvent se prsenter comme suit:

    9.2. Les pointeursUnpointeur est une variable spciale qui peut contenir l'adresse d'une autre variable.

    En C, chaque pointeur est limit un type de donnes. 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'.

    Remarque

    Les pointeurs et les noms de variables ont le mme rle: Ils donnent accs un emplacement

    dans la mmoire interne de l'ordinateur. Il faut quand mme bien faire la diffrence:

    Unpointeur est une variable qui peut 'pointer' sur diffrentes adresses. Lenom d'une variable reste toujours li la mme adresse.

    9.2.1. Les oprateurs de baseLors du travail avec des pointeurs, on aura besoin- d'un oprateur adresse de : & pour obtenir l'adresse d'une variable.

    - d'un oprateur contenu de : * pour accder au contenu d'une adresse.- d'une syntaxe de dclaration pour pouvoir dclarer un pointeur.

    9.2.1.1. L'oprateur 'adresse de' : && : fournit l'adresse de la variable

    L'oprateur & est dj vu avec la fonction scanf, qui a besoin de l'adresse de ses argumentspour pouvoir leur attribuer de nouvelles valeurs.

    Exempleint N;printf("Entrez un nombre entier : ");scanf("%d", &N);

    L'oprateur & peut seulement tre appliqu des objets qui se trouvent dans la mmoire

    interne, c'est--dire des variables et des tableaux. Il ne peut pas tre appliqu desconstantes ou des expressions.

    Soit P un pointeur non initialis

    et A une variable (du mme type) contenant la valeur 10 :

  • 8/6/2019 cours pointeurs

    3/15

    Les Pointeurs Environnements de Dveloppement (Langage C)

    Alors l'instruction P = &A; affecte l'adresse de la variable A la variable P. En mmoire, A

    et P se prsentent comme dans le graphique donn la section 9.1.2. Dans notrereprsentation schmatique, nous pouvons illustrer le fait que 'P pointe sur A' par une flche:

    9.2.1.2. L'oprateur 'contenu de' : ** : dsigne le contenu de l'adresse rfrence par le pointeur

    Exemple

    Soit A une variable contenant la valeur 10, B une variable contenant la valeur 50 et P un

    pointeur non initialis:

    Aprs les instructions,P = &A;B = *P;*P = 20;

    - P pointe sur A,- le contenu de A (rfrenc par *P) est affect B, et- le contenu de A (rfrenc par *P) est mis 20.

    Dclaration d'un pointeur * : dclare un pointeur qui peut recevoir des

    adresses de variables du type

    Une dclaration comme int *PNUM; peut tre interprte comme suit:

    "*PNUM est du type int"

    ou

    "PNUM est un pointeur sur int"

    ou"PNUM peut contenir l'adresse d'une variable du type int"

  • 8/6/2019 cours pointeurs

    4/15

  • 8/6/2019 cours pointeurs

    5/15

    Les Pointeurs Environnements de Dveloppement (Langage C)

    En outre:

    &P dsigne l'adresse du pointeur P

    *A est illgal (puisque A n'est pas un pointeur)

    9.3.

    Pointeurs et tableauxEn C, il existe une relation trs troite entre tableaux et pointeurs. Ainsi, chaque opration

    avec des indices de tableaux peut aussi tre exprime l'aide de pointeurs. En gnral, les

    versions formules avec des pointeurs sont plus compactes et plus efficientes, surtout

    l'intrieur de fonctions.

    9.3.1. Adressage des composantes d'un tableauComme on l'a dj constat au chapitre 6, le nom d'un tableau reprsente l'adresse de son

    premier lment. En d'autre termes: &tableau[0] et tableau sont une seule et mme adresse.

    En simplifiant, on peut retenir que le nom d'un tableau est unpointeurconstant sur lepremier lment du tableau.

    Exemple

    En dclarant un tableau A de type int et un pointeur P sur int,int A[10];int *P;

    l'instruction:

    P = A; est quivalente P = &A[0];Si P pointe sur une composante quelconque d'un tableau, alors P+1 pointe sur la composante

    suivante. Plus gnralement,

    P+ipointe sur la i-ime composante derrire P etP-i pointe sur la i-ime composante devant P.

    Ainsi, aprs l'instruction,

    P = A;le pointeur P pointe sur A[0], et

    *(P+1)dsigne le contenu de A[1]

    *(P+2)dsigne le contenu de A[2]

    ... ...

    *(P+i) dsigne le contenu de A[i]

    RemarqueAu premier coup d'oeil, il est bien surprenant que P+i n'adresse pas le i-ime octet derrire P,

    mais la i-ime composante derrire P. Ceci s'explique par la stratgie de programmation

    'dfensive' des crateurs du langage C: Si on travaille avec des pointeurs, les erreurs les plus

    perfides sont causes par des pointeurs mal placs et des adresses mal calcules. En C, le

    compilateur peut calculer automatiquement l'adresse de l'lment P+i en ajoutant P la

    grandeur d'une composante multiplie par i. Ceci est possible, parce que:- chaque pointeur est limit un seul type de donnes, et- le compilateur connat le nombre d'octets des diffrents types.

    Exemple

    Soit A un tableau contenant des lments du type float et P un pointeur sur float:float A[20], X;float *P;

  • 8/6/2019 cours pointeurs

    6/15

    Les Pointeurs Environnements de Dveloppement (Langage C)

    Aprs les instructions,P = A;X = *(P+9);

    X contient la valeur du 10-ime lment de A, (c'est--dire celle de A[9]). Une donne du

    type float ayant besoin de 4 octets, le compilateur obtient l'adresse P+9 en valuantlexpression suivante : 9* sizeof(float) = 9*4 = 36, ainsi, il ajoute 36 octets l'adresse de P.

    Ainsi, Comme A reprsente l'adresse de A[0],

    *(A+1)dsigne le contenu de A[1]

    *(A+2)dsigne le contenu de A[2]

    ...

    *(A+i)dsigne le contenu de A[i]

    Attention !Il existe toujours une diffrence essentielle entre un pointeur et le nom d'un tableau:

    -

    Un pointeur est une variable, donc des oprations comme P = A ou P++ sontpermises.- Le nom d'un tableau est une constante, donc des oprations comme A = P ou A++

    sont impossibles.

    9.3.2. Arithmtique des pointeursComme les pointeurs jouent un rle si important, le langage C soutient une srie d'oprations

    arithmtiques sur les pointeurs que l'on ne rencontre en gnral que dans les langages

    machines. Le confort de ces oprations en C est bas sur le principe suivant:

    Toutes les oprations avec les pointeurs tiennent compte automatiquement du type et de la

    grandeur des objets points.

    - Affectation par un pointeur sur le mme type Soient P1 et P2 deux pointeurs sur le mme type de donnes, alors l'instruction P1 = P2; faitpointer P1 sur le mme objet que P2.

    - Addition et soustraction d'un nombre entierSi P pointe sur l'lment A[i] d'un tableau, alors

    P+npointe sur A[i+n]

    P-n pointe sur A[i-n]

    - Incrmentation et dcrmentation d'un pointeurSi P pointe sur l'lment A[i] d'un tableau, alors aprs l'instruction

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

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

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

    P-=n; P pointe sur A[i-n]

    Domaine des oprationsL'addition, la soustraction, l'incrmentation et la dcrmentation sur les pointeurs sont

    seulement dfinies l'intrieur d'un tableau. Si l'adresse forme par le pointeur et l'indice sortdu domaine du tableau, alors le rsultat n'est pas dfini.

  • 8/6/2019 cours pointeurs

    7/15

    Les Pointeurs Environnements de Dveloppement (Langage C)

    Seule exception: Il est permis de 'pointer' sur le premier octet derrire un tableau ( condition

    que cet octet se trouve dans le mme segment de mmoire que le tableau). Cette rgle,introduite avec le standard ANSI-C, lgalise la dfinition de boucles qui incrmentent le

    pointeur avantl'valuation de la condition d'arrt.

    - Soustraction de deux pointeursSoient P1 et P2 deux pointeurs qui pointent dans le mme tableau:

    P1-P2fournit le nombre de composantes comprises entre P1 et P2.

    Le rsultat de la soustraction P1-P2 est

    * ngatif, si P1 prcde P2

    * nul, si P1 = P2

    * positif, si P2 precde P1

    * indfini, si P1 et P2 ne pointent pas dans le mme tableau

    Plus gnralement, la soustraction de deux pointeurs qui pointent dans le mme tableau est

    quivalente la soustraction des indices correspondants.

    - Comparaison de deux pointeursOn peut comparer deux pointeurs par , =, ==, !=.La comparaison de deux pointeurs qui pointent dans le mme tableau est quivalente la

    comparaison des indices correspondants. (Si les pointeurs ne pointent pas dans le mme

    tableau, alors le rsultat est donn par leurs positions relatives dans la mmoire).

    9.3.3. Pointeurs et chanes de caractresDe la mme faon qu'un pointeur sur int peut contenir l'adresse d'un nombre isol ou d'une

    composante d'un tableau, un pointeur sur char peut pointer sur un caractre isol ou sur leslments d'un tableau de caractres. Un pointeur sur char peut en plus contenir l'adressed'une chane de caractres constante et il peut mme tre initialisavec une telle adresse.

    a)AffectationOn peut attribuer l'adresse d'une chane de caractres constante un pointeur sur char:char *C;C = "Ceci est une chane de caractres constante";

    Nous pouvons lire cette chane constante (p.ex: pour l'afficher), mais il n'est pas recommand

    de la modifier, parce que le rsultat d'un programme qui essaie de modifier une chane de

    caractres constante n'est pas prvisible en ANSI-C.

    b)InitialisationUn pointeur sur char peut tre initialis lors de la dclaration si on lui affecte l'adresse d'unechane de caractres constante:

    char *B = "Bonjour !";

    Il est noter, quil existe une diffrence importante entre les deux dclarations:char A[] = "Bonjour !"; /* un tableau */char *B = "Bonjour !"; /* un pointeur */

  • 8/6/2019 cours pointeurs

    8/15

    Les Pointeurs Environnements de Dveloppement (Langage C)

    A est un tableau qui a exactement la grandeur pour contenir la chane de caractres et la

    terminaison '\0'. Les caractres de la chane peuvent tre changs, mais le nom A va toujourspointer sur la mme adresse en mmoire.

    B est un pointeur qui est initialis de faon ce qu'il pointe sur une chane de caractresconstante stocke quelque part en mmoire. Le pointeur peut tre modifi et pointer sur autre

    chose. La chane constante peut tre lue, copie ou affiche, mais pas modifie.

    c)ModificationSi nous affectons une nouvelle valeur un pointeur sur une chane de caractres constante,

    nous risquons de perdre la chane constante. D'autre part, un pointeur sur char a l'avantage depouvoir pointer sur des chanes de n'importe quelle longueur:

    char *A = "Petite chane";char *B = "Deuxime chane un peu plus longue";A = B;

    Maintenant A et B pointent sur la mme chane; la "Petite chane" est perdue:

    Attention !Les affectations discutes ci-dessus ne peuvent pas tre effectues avec des tableaux de

    caractres:

    char A[45] = "Petite chane";char B[45] = "Deuxime chane un peu plus longue";char C[30]; A = B; /* IMPOSSIBLE -> ERREUR !!! */

    C = "Bonjour !"; /* IMPOSSIBLE -> ERREUR !!! */

    Dans cet exemple, nous essayons de copier l'adresse de B dans A, respectivement l'adresse dela chane constante dans C. Ces oprations sont impossibles et illgales parce que l'adresse

    reprsente par le nom d'un tableau reste toujours constante.

    Pour changer le contenu d'un tableau, nous devons changer les composantes du tableau l'une

    aprs l'autre (p.ex. dans une boucle) ou dlguer cette charge une fonction de ou

    .

    9.3.4. Pointeurs et tableaux deux dimensionsL'arithmtique des pointeurs se laisse largir avec toutes ses consquences sur les tableaux

    deux dimensions. Voyons cela sur un exemple:

    Le tableau M deux dimensions est dfini comme suit:

  • 8/6/2019 cours pointeurs

    9/15

    Les Pointeurs Environnements de Dveloppement (Langage C)

    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 reprsente l'adresse du premier lment du tableau et pointe sur le

    tableau M[0] qui a la valeur:

    {0,1,2,3,4,5,6,7,8,9}.L'expression (M+1) est l'adresse du deuxime lment du tableau et pointe sur M[1] qui a la

    valeur:

    {10,11,12,13,14,15,16,17,18,19}.Au sens strict du terme, un tableau deux dimensions est un tableau unidimensionnel dontchaque composante est un tableau unidimensionnel. Ainsi, le premier lment de la matrice M

    est le vecteur{0,1,2,3,4,5,6,7,8,9}, le deuxime lment est {10,11,12,13,14,15,16,17,18,19}et ainsi de suite.

    L'arithmtique des pointeurs qui respecte automatiquement les dimensions des lments

    conclut logiquement que: M+I dsigne l'adresse du tableau M[I]

    Ainsi, le problme qui se pose est : comment pouvons-nous accder l'aide de pointeurs aux

    lments de chaque composante du tableau, c'est--dire aux lments M[0][0], M[0][1], ... ,M[3][9] ?

    - Une premire solution consiste convertir la valeur de M (qui est un pointeur sur untableau du type int) en un pointeur sur int. On pourrait se contenter de procder ainsi:

    int *P;P = M; /* conversion automatique */

    Cette dernire affectation entrane une conversion automatique de l'adresse &M[0]

    dans l'adresse &M[0][0] (l'adresse transmise reste la mme, seule la nature du pointeur

    a chang).Cette solution n'est pas satisfaisante cent pour-cent car elle ne peut pas viter les

    messages davertissement lancs de la part du compilateur.

    - Une deuxime solution qui est plus satisfaisante consiste en ce qui suit :int *P;P = (int *)M; /* conversion force */

    Gnralement, on gagne en lisibilit en explicitant la conversion mise en oeuvre parl'oprateur de conversion force ("cast"), qui vite les messages d'avertissement de la

    part du compilateur.

    D la mmorisation ligne par ligne des tableaux deux dimensions, il nous est maintenant

    possible traiter M l'aide du pointeur P comme un tableau unidimensionnel de dimension

    4*10.

    Par exemple, si on cherche calculer la somme de tous les lments du tableau M, on peut

    crire lensemble des instructions suivantes :

    int *P;int I, SOM;P = (int*)M;SOM = 0;for (I=0; I

  • 8/6/2019 cours pointeurs

    10/15

    Les Pointeurs Environnements de Dveloppement (Langage C)

    9.3.5. Pointeurs vers des structuresSoit la structure Navire suivante :

    typedef struct{

    char nom[32];unsigned int anConst;unsigned int nbPassagers;unsigned int taille_equipage;

    } Navire;

    Afin de dclarer une variable de type pointeur vers cette structure, on procde comme suit :Navire *p;

    On peut affecter ce pointeur des adresses sur des Navire. Par exemple :

    int main() { Navire nav; // nav = variable de type Navire

    Navire * p_nav; // p_nav = pointeur vers une structure de type Navire p_nav = &nav; // p_nav pointe maintenant vers nav

    }

    Pour accder aux membres de la structure pointe, il faudrait crire normalement

    (*p_nav).nom;

    Exemple

    printf("Le navire %s est construit en %d", (*p_nav).nom, (*p_nav).anConst);

    Mais l'criture prcdente est complexe, pour cela on utilise en pratique une criture

    simplifie offerte par l'oprateur "->" :p_nav->nom.

    Ainsi, les deux critures ci-dessous sont quivalentes :(*p_nav).nom et p_nav->nom

    On peut alors reprendre notre exemple de la manire suivante :

    printf("Le navire %s est construit en %d", p_nav->nom, p_nav->anConst);

    9.4. Tableaux de pointeursDclaration

    *[]

    dclare un tableau de pointeurs sur des donnes du type .

    Exempledouble *A[10];

    dclare un tableau de 10 pointeurs sur des rationnels du type double dont les adresses et les

    valeurs ne sont pas encore dfinies.

    Remarque

    Le plus souvent, les tableaux de pointeurs sont utiliss pour mmoriser de faon conomiquedes chanes de caractres de diffrentes longueurs.

  • 8/6/2019 cours pointeurs

    11/15

    Les Pointeurs Environnements de Dveloppement (Langage C)

    Initialisation

    Nous pouvons initialiser les pointeurs d'un tableau sur char par les adresses de chanes decaractres constantes.

    Exemplechar *JOUR[] = {"dimanche", "lundi", "mardi", "mercredi", "jeudi","vendredi", "samedi"};

    dclare un tableau JOUR[] de 7 pointeurs sur char. Chacun des pointeurs est initialis avecl'adresse de l'une des 7 chanes de caractres.

    On peut afficher les 7 chanes de caractres en fournissant les adresses contenues dans le

    tableau JOUR printf(ou puts) :int I;for (I=0; I

  • 8/6/2019 cours pointeurs

    12/15

    Les Pointeurs Environnements de Dveloppement (Langage C)

    Exemplesfloat A, B, C; /* rservation de 12 octets (4+4+4) */short D[10][20]; /* rservation de 400 octets (2*10*20)*/char E[] = "Bonjour !"; /* rservation de 10 octets */char F[][10] = {"un", "deux", "trois", "quatre"}; /* rservation de 40

    octets (4*10) */

    PointeursLe nombre d'octets rserver pour un pointeur dpend de la machine et du 'modle' de

    mmoire choisi, mais il est dj connu lors de la compilation. Un pointeur est donc aussi

    dclar statiquement. Supposons dans la suite qu'un pointeur ait besoin de p octets enmmoire. (sous DOS: p =2 ou p = 4)

    Exemplesdouble *G; /* rservation de p octets */char *H; /* rservation de p octets */float *I[10]; /* rservation de 10*p octets */

    Chanes de caractres constantesL'espace pour les chanes de caractres constantes qui sont affectes des pointeurs ou

    utilises pour initialiser des pointeurs sur char est aussi rserv automatiquement:

    Exempleschar *J = "Bonjour !"; /* rservation de p+10 octets (p pourJ et 10 pour la chane "Bonjour !"*/

    float *K[] = {"un", "deux", "trois", "quatre"}; /* rservation de4*p+3+5+6+7 octets */

    9.5.2. Allocation dynamiqueSouvent, nous devons travailler avec des donnes dont nous ne pouvons pas prvoir le nombreet la grandeur lors de la programmation. Ce serait alors un gaspillage de rserver toujours

    l'espace maximal prvisible. Il nous faut donc un moyen de grer la mmoire lors de

    l'excution du programme.

    Par exemple, si nous voulons lire 10 phrases au clavier et mmoriser les phrases en utilisantun tableau de pointeurs sur char.

    Nous dclarons ce tableau de pointeurs par: char *TEXTE[10];Pour les 10 pointeurs, nous avons besoin de 10*p octets. Ce nombre est connu ds le dpart et

    les octets sont rservs automatiquement. Il nous est cependant impossible de prvoir

    l'avance le nombre d'octets rserver pour les phrases elles-mmes qui seront introduites lors

    de l'excution du programme.La rservation de la mmoire pour les 10 phrases peut donc seulement se faire pendant

    l'excution du programme. Nous parlons dans ce cas de l' allocation dynamique de lammoire.

    9.5.3. Les fonctions dallocation et de libration dynamique de la mmoireAfin dallouer dynamiquement de la mmoire, nous pouvons nous servir dun ensemble de

    fonctions prdfinies offertes dans la bibliothque . Toutes les fonctions donnes ci-

    dessous retournent les adresses des zones alloues, c'est--dire des pointeurs vers ces zones.

    Ces pointeurs sont de type void *. Ainsi, pour viter les problmes dincompatibilit de types,

  • 8/6/2019 cours pointeurs

    13/15

    Les Pointeurs Environnements de Dveloppement (Langage C)

    nous devons convertir ces pointeurs laide dun cast, en des pointeurs ayant le type des

    variables pour lesquelles ces zones ont t rserves.

    Exemple

    char* mot = "Hello" ;char* memeMot ;memeMot = (char*) malloc (strlen (mot)+1) ;

    Bien entendu, le langage C offre aussi le moyen de librer dune manire dynamique une zone

    que nous avons rserve dynamiquement.

    9.5.3.1. La fonction La fonction malloc nous aide localiser et rserver de la mmoire au cours d'un

    programme. Elle nous donne accs au tas (heap); c'est--dire l'espace en mmoire laiss

    libre une fois mis en place le systme dexploitation, les gestionnaires, les programmes

    rsidents, le programme lui-mme et la pile (stack).

    Le prototype de est comme suit :

    void * malloc (size_tsize);

    Elle sert fournir ladresse dun bloc en mmoire de taille size octets, si la rservation a

    russi, sinon (pas assez de mmoire) elle renvoie la valeur zro. Le contenu de la zone de

    mmoire n'est pas initialis.

    Sur un systme DOS, le paramtre size est du type unsignedint. A l'aide de malloc, nous ne

    pouvons donc pas rserver plus de 65535 octets la fois.

    Exemple

    Supposons que nous ayons besoin d'un bloc en mmoire pour un texte de 4000 caractres.Nous disposons d'un pointeur T sur char (char *T). Alors l'instruction:

    T = (char*) malloc(4000);

    fournit l'adresse d'un bloc de 4000 octets libres et l'affecte T. S'il n'y a plus assez de

    mmoire, T obtient la valeur zro.Si nous voulons rserver de la mmoire pour des donnes d'un type dont la grandeur varie

    d'une machine l'autre, nous avons besoin de la grandeur effective d'une donne de ce type.L'oprateur sizeofnous aide alors prserver la portabilit du programme.

    a. L'oprateur unaire sizeof fournit la grandeur de la variable

    sizeof fournit la grandeur de la constante

    sizeof () fournit la grandeur pour un objet du type

    ExempleNous voulons rserver de la mmoire pour X valeurs du type int; la valeur de X est lue au

    clavier:

    int X;int *PNum;printf("Introduire le nombre de valeurs :");

    scanf("%d", &X);PNum = (int*) malloc(X*sizeof(int));

  • 8/6/2019 cours pointeurs

    14/15

    Les Pointeurs Environnements de Dveloppement (Langage C)

    b. La commande S'il n'y a pas assez de mmoire pour effectuer une action avec succs, il est conseill

    d'interrompre l'excution du programme l'aide de la commande exit (de ) et derenvoyer une valeur diffrente de zro comme code d'erreur du programme (voir aussi

    chapitre 10.4).

    ExempleLe programme suivant lit 10 phrases au clavier, recherche des blocs de mmoire libres assez

    grands pour la mmorisation et passe les adresses aux composantes du tableau TEXTE[]. S'iln'y a pas assez de mmoire pour une chane, le programme affiche un message d'erreur et

    interrompt le programme avec le code d'erreur -1.

    Nous devons utiliser une variable d'aide INTRO comme zone intermdiaire (non dynamique).

    Pour cette raison, la longueur maximale d'une phrase est fixe 500 caractres.

    #include

    #include #include

    main(){/* Dclarations */char INTRO[500];char *TEXTE[10];int I;

    /* Traitement */for (I=0; I

  • 8/6/2019 cours pointeurs

    15/15

    Les Pointeurs Environnements de Dveloppement (Langage C)

    9.5.3.3. La fonction Le prototype de cette fonction est le suivant :

    void * realloc (void *ptr, size_tsize);

    Elle sert modifier (rallonger ou raccourcir) la taille du bloc de mmoire point par ptr pourl'amener une taille de size octets. realloc() conserve le contenu de la zone mmoireminimum entre la nouvelle et l'ancienne taille. Le contenu de la zone mmoire nouvellement

    alloue n'est pas initialis. Siptrest NULL, l'appel de realloc() est quivalent malloc(size).Si size vaut zro, l'appel est quivalent free(ptr). Siptrn'est pas NULL, il doit avoir t

    obtenu par un appel antrieur malloc(), calloc() ou realloc().

    Exemple 1

    int *p = (int *) malloc(10 * sizeof(int)); p = realloc(p, 5 * sizeof(int));

    Dans cet exemple, nous avons rduit la taille de la zone pointe par p. Ainsi, seuls les 5

    premiers entiers seront effectifs, les 5 autres ne seront plus considrs.

    Exemple 2

    int *p = (int *) malloc(10 * sizeof(int)); p = (int*) realloc(p, 35 * sizeof(int));

    Dans cet exemple, nous avons augment la taille de la zone pointe par p. Le problme que

    cela peut poser est que la zone dans laquelle se trouve le tableau compos de seulement 10lments ne lui permet peut-tre pas dtre agrandi sans dborder sur dautres donnes.

    realloc() alloue, dans ce cas, les 35 lments dans une autre partie du tas et recopie dans les

    10 premiers lments leurs valeurs originales.

    9.5.3.4. La fonction freeSi nous n'avons plus besoin d'un bloc de mmoire que nous avons rserv l'aide de malloc,

    alors nous pouvons le librer l'aide de la fonction free de la bibliothque .free( )

    libre le bloc de mmoire dsign par le ; n'a pas d'effet si le pointeur a la valeur

    zro.

    Attention !* La fonction free peut aboutir un dsastre si on essaie de librer de la mmoire qui n'a past alloue par malloc.

    * La fonction free ne change pas le contenu du pointeur; il est conseill d'affecter la valeurzro au pointeur immdiatement aprs avoir libr le bloc de mmoire qui y tait attach.

    Exemple : free(TEXTE[I]) ;TEXTE[I] = 0 ;

    * Si nous ne librons pas explicitement la mmoire l'aide de free, alors elle est libre

    automatiquement la fin du programme.