0% ont trouvé ce document utile (0 vote)
28 vues19 pages

Chap 4

Ce document traite des pointeurs en langage C, expliquant leur définition, déclaration, manipulation, et leur utilisation avec des structures et des tableaux. Il aborde également l'allocation dynamique de mémoire et la gestion des chaînes de caractères. Les pointeurs sont présentés comme des outils essentiels pour la gestion de la mémoire et l'accès indirect aux variables.

Transféré par

Issa Ba
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
28 vues19 pages

Chap 4

Ce document traite des pointeurs en langage C, expliquant leur définition, déclaration, manipulation, et leur utilisation avec des structures et des tableaux. Il aborde également l'allocation dynamique de mémoire et la gestion des chaînes de caractères. Les pointeurs sont présentés comme des outils essentiels pour la gestion de la mémoire et l'accès indirect aux variables.

Transféré par

Issa Ba
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

UNIVERSITÉ AMADOU MAHTAR MBOW (UAM)

ÉCOLE SUPÉRIEURE DES SCIENCES ET TECHNIQUES


DE L’INGÉNIEUR

LICENCE 2 INGÉNIERIE INFORMATIQUE

Chapitre 4 – Les Pointeurs


Programmation en LANGAGE C

2022 - 2023
1
I. Introduction: notion d'adresse

La mémoire centrale utilisée par les programmes, est découpée en


octets. Chacun de ces octets est identifié par un numéro
séquentiel. Par convention, ce numéro est noté en hexadécimal et
précédé par 0x.

Exemple :

Déclarer une variable consiste à réserver une zone en mémoire


occupant un certain nombre d‘octets (sa taille) et à laquelle on donne
un nom. Le numéro du premier octet de cette zone correspond à
l‘adresse de la variable.
2
Exemple :
short int n = 18;

Dans cet exemple, la valeur de la variable n est 18 et son adresse


est 0x3fffd14.

Pour accéder à la valeur contenue dans une variable, on utilise


tout simplement son nom.
Toutefois, il est parfois très pratique de manipuler une
variable par son adresse. 3
II. Notion de pointeur
II-1. Définition
Un pointeur est une variable dont la valeur est l'adresse d'une
autre variable.
On dit que le pointeur pointe sur la variable dont il contient
l'adresse.

Un pointeur est associé à un type de variable sur lequel il peut pointer.


Par exemple, un pointeur sur entier ne peut pointer que sur des variables
entières.
Un pointeur est lui-même une variable et à ce titre il possède une
adresse.

4
Il convient de ne pas confondre l'adresse de la
variable pointeur et l'adresse contenue dans le
pointeur (adresse de la variable pointée).

Représentation :

pointeur

variable
pointée
Exemple :

p
n
18

5
II-2. Déclaration d'un pointeur
syntaxe :
type * nom_pointeur;
Exemple :
int * p;

II-3. Manipulation d'un pointeur


Après avoir déclaré un pointeur, on peut l’initialiser en lui
donnant l’adresse d’une variable existante.
Exemple :
main()
{
int n;
int * p;

p = &n;
… }
6
Il est possible d’accéder à la zone mémoire pointée en utilisant
l‘opérateur *. Ainsi, *p désigne la zone mémoire (la variable)
pointée par le pointeur p.
Exemple :
main()
{
int n = 33;
int *p; //déclaration du pointeur p
p = &n; // p pointe sur n
printf("%d", *p) ; //affiche 33 à l'écran, la valeur de n
*p = 34 ; // n vaut maintenant 34
}
Remarque
Par défaut lorsque l’on déclare un pointeur, on ne sait pas sur
quoi il pointe. Si on veut que le pointeur pointe nulle part, il
faut l'initialiser à NULL.
Exemple :
int * p = NULL ; 7
II-4. Double indirection
Le fait qu'un pointeur pointe sur une variable s'appelle indirection
(comme accès indirect). Quand un pointeur pointe sur un autre
pointeur, il y a double indirection.
Exemple :

On peut accéder à n par p2 en utilisant deux fois l'opérateur *

8
* *p2 est équivalent à *p1 et à n
III. Allocation dynamique de
mémoire
Au lieu d’affecter à un pointeur l’adresse d’une variable existante,
on peut réserver de manière dynamique une nouvelle zone en
mémoire et affecter au pointeur l’adresse de cette zone. Le
pointeur va alors pointer sur cette zone.
En C, l’allocation dynamique de mémoire peut se faire avec les
fonctions malloc et calloc de la bibliothèque standard stdlib.h:

- La fonction malloc prend comme paramètre la taille de la zone


qu’on veut allouer et retourne, en cas de succès, l’adresse de la
zone allouée. Le type de l’adresse retournée par malloc est void*.
Il faut alors le convertir au type du pointeur auquel on va l‘affecter.
Exemple :
si on veut réserver un nouvel emplacement pour un caractère, on peut
faire:
char *pcar;
pcar = (char *)malloc(sizeof(char ));
9
En cas d’échec, la fonction malloc retourne NULL.

- La fonction calloc prend en paramètre un nombre d’éléments


nb et la taille t d’un élément et permet d’allouer une zone
contiguë de nb éléments de taille t octets.

Elle retourne, en cas de succès, l’adresse de la zone allouée.


Le type de l’adresse retournée par calloc est void*. Il faut alors
le convertir au type du pointeur auquel on va l‘affecter.

Exemple :
si on veut allouer un emplacement pour 10 éléments de type int,
on peut faire:

int * p;
p = (int *)calloc(10, sizeof(int));

En cas d’échec, la fonction calloc retourne NULL. 10


Remarque

La libération d’une zone mémoire allouée de manière


dynamique n’est pas automatique en C.
Une telle zone continue à occuper de l’espace mémoire jusqu’à la
fin de l’exécution du programme si on ne la libère pas de manière
explicite. Pour ce faire, il faut utiliser la fonction free de la
bibliothèque standard stdio.h selon la syntaxe suivante:

free(nom_pointeur);

Exemple :
free(p);
permet de libérer la zone mémoire pointée par p.

11
IV. Pointeurs et structures

Il est très courant d'utiliser un pointeur pour mémoriser


l'adresse d'une variable structure.

Si p est un pointeur sur une structure, *p désigne la


structure pointée.
On peut donc accéder à un champ de la structure pointée
par l'expression : (*p).champ
L'usage de parenthèses est ici indispensable car
l'opérateur * a une priorité moins élevée que l'opérateur
point (.).

Cette notation peut être simplifiée grâce à l'opérateur ->.


L'expression précédente est strictement équivalente à :
p->champ

12
Exemple :

struct date
{
int jour;
int mois;
int annee;
};

struct date d; // d est une variable structure


struct date * p;//p est un pointeur sur une structure

p = &d // p pointe sur la structure d

Alors d.jour est équivalent à p jour


13
V. Arithmétique des pointeurs

Si i est un entier et p est un pointeur sur un objet de type unType,


l'expression p + i désigne un pointeur sur un objet de type unType
dont la valeur est égale à la valeur de p incrémentée de
i*sizeof(unType).
Il en va de même pour la soustraction d'un entier à un pointeur, et pour
les opérateurs d'incrémentation et de décrémentation ++ et --.

Ainsi, pour un pointeur sur un char, l’incrémentation de ce pointeur


correspond à un décalage de 1 octet de la zone mémoire pointée,
alors que pour un pointeur sur un float, la même incrémentation
correspondra à un décalage de 4 octets.

Soient p1 et p2 deux pointeurs de même type. L’instruction


p1 = p2;
signifie qu’on copie dans p1 l’adresse contenue dans p2 et, donc, que p1
va pointer au même endroit que p2.

14
VI. Pointeurs et tableaux
L'usage des pointeurs en C est, en grande partie, orienté vers la
manipulation des tableaux.

En C, le nom d’un tableau est en fait un pointeur sur le premier


élément du tableau.
Exemple :
dans la déclaration
int tab[10];
tab est un pointeur constant dont la valeur est l'adresse du premier
élément du tableau. Autrement dit, tab a pour valeur &tab[0]. Cette
valeur n’est pas modifiable, néanmoins elle peut être utilisée pour
initialiser un pointeur sur le premier élément du tableau.
Exemple :
int tab[5]={1,2,3,4,5};
int * p = tab;
p pointe au même endroit que tab c’est à dire sur le premier élément
du tableau

tab étant un pointeur sur le premier élément (élément d’indice 0) du15


tableau, tab+i donne le pointeur vers l’élément d’indice i du tableau.
Un tableau correspond en mémoire à un zone contiguë dont la taille est le
produit du nombre d’éléments du tableau par l’espace nécessaire pour
stocker un élément. On peut donc utiliser un pointeur pour accéder
aux différents éléments d’un tableau.

Exemple :
Programme qui affiche un tableau d’entiers
#include <stdio.h>
#define N 5
main()
{
int tab[5] = {1, 2, 6, 0, 7};
int *p;
for (p=tab; p<=tab+N-1; p++)
printf(" %d \n",*p);
}

16
Remarque
On peut déclarer un tableau comme un pointeur sur le type de ses
éléments.
Exemple :
int * tab;
Mais dans ce cas, aucune place n’est réservée en mémoire pour le
tableau et le pointeur tab n’est pas un pointeur constant.
Pour faire la réservation en mémoire, on peut utiliser les fonctions
d’allocation dynamique malloc ou calloc.

Exemple :
int * tab;
int nb=10;
tab = (int *)malloc(nb*sizeof(int));
ou bien
tab = (int *)calloc(nb, sizeof(int));
On peut ensuite utiliser tab comme un tableau normal.

Exemple :
pour désigner l’élément i de ce tableau, on peut écrire
17
tab[i] ou *(tab+i);
VII. Pointeurs et chaînes de caractères en C
On a vu précédemment qu'une chaîne de caractères était un tableau à une
dimension d'éléments de type char, se terminant par le caractère nul ‘\0’.
Le nom d’un tableau étant un pointeur sur le premier élément, on peut donc
manipuler toute chaîne de caractères à l'aide d'un pointeur sur un
élément de type char.
Ainsi, il existe deux manières de déclarer une chaîne de caractères :

- Comme un tableau de caractères:

Exemple :

char ch[10];

Dans ce cas il y a réservation d’espace mémoire pour la chaîne et le nom de


la chaîne (ch) est un pointeur constant et ne peut donc pas apparaître
dans le membre gauche d'une affectation. On dit dans ce cas que
l'espace mémoire nécessaire au stockage des caractères de la chaîne est
réservé "statiquement".

18
- Comme un pointeur sur un caractère:

Exemple :
char * ch;

Dans ce cas il n’y a pas de réservation d’espace mémoire


pour la chaîne. Pour faire la réservation en mémoire, on
peut utiliser les fonctions d’allocation dynamique malloc
ou calloc.
Le pointeur ch n’est pas un pointeur constant et peut
apparaître dans le membre gauche d'une affectation.

Exemple :
ch = "bonjour";

19

Vous aimerez peut-être aussi