Vous êtes sur la page 1sur 45

Introduction

Les pointeurs
Pointeurs et fonctions
Pointeurs et tableaux

Structures de données en C

Laila AMIR

Tronc commun MIP & MIPC

Année universitaire 2018/2019

Laila AMIR
Introduction
Les pointeurs
Pointeurs et fonctions
Pointeurs et tableaux

Plan
1 Introduction
Intérêt des pointeurs
2 Les pointeurs
Notion d’un pointeur
Les opérateurs de base &, *
Déclaration d’un pointeur
Initialisation d’un pointeur
Accéder à une variable pointée
3 Pointeurs et fonctions
Portée d’une variable
Passage de paramètres par valeur ou par adresse
4 Pointeurs et tableaux
Pointeurs et tableaux à une dimension
Pointeurs et tableaux à plusieurs dimensions
Laila AMIR
Introduction
Les pointeurs
Intérêt des pointeurs
Pointeurs et fonctions
Pointeurs et tableaux

Outline
1 Introduction
Intérêt des pointeurs
2 Les pointeurs
Notion d’un pointeur
Les opérateurs de base &, *
Déclaration d’un pointeur
Initialisation d’un pointeur
Accéder à une variable pointée
3 Pointeurs et fonctions
Portée d’une variable
Passage de paramètres par valeur ou par adresse
4 Pointeurs et tableaux
Pointeurs et tableaux à une dimension
Pointeurs et tableaux à plusieurs dimensions
Laila AMIR
Introduction
Les pointeurs
Intérêt des pointeurs
Pointeurs et fonctions
Pointeurs et tableaux

Intérêt des pointeurs

Les pointeurs ont un grand nombre d’intérêts :


Ils permettent de manipuler de façon simple des données
importantes (au lieu de passer à une fonction un élément de
taille très grande on pourra lui fournir un pointeur vers cet
élément)
Le passage des paramètres en C se fait toujours par la valeur, les
pointeurs sont le seul moyen de changer le contenu de variables
déclarées dans d’autres fonctions.

Laila AMIR
Introduction
Les pointeurs
Intérêt des pointeurs
Pointeurs et fonctions
Pointeurs et tableaux

Intérêt des pointeurs

La notion de pointeur est une technique de programmation très


puissante, permettant de définir des structures dynamiques, c-à-d
qui évoluent au cours du temps (par opposition aux tableaux qui
sont des structures de données statiques, dont la taille est figée,
fixée à la définition).

Ainsi le traitement de tableaux et de chaı̂nes de caractères dans


des fonctions serait impossible sans l’utilisation de pointeurs.

Il est possible de créer des structures chaı̂nées, c’est-à-dire


comportant des maillons liés par des pointeurs.

Laila AMIR
Notion d’un pointeur
Introduction
Les opérateurs de base &, *
Les pointeurs
Déclaration d’un pointeur
Pointeurs et fonctions
Initialisation d’un pointeur
Pointeurs et tableaux
Accéder à une variable pointée

Outline
1 Introduction
Intérêt des pointeurs
2 Les pointeurs
Notion d’un pointeur
Les opérateurs de base &, *
Déclaration d’un pointeur
Initialisation d’un pointeur
Accéder à une variable pointée
3 Pointeurs et fonctions
Portée d’une variable
Passage de paramètres par valeur ou par adresse
4 Pointeurs et tableaux
Pointeurs et tableaux à une dimension
Pointeurs et tableaux à plusieurs dimensions
Laila AMIR
Notion d’un pointeur
Introduction
Les opérateurs de base &, *
Les pointeurs
Déclaration d’un pointeur
Pointeurs et fonctions
Initialisation d’un pointeur
Pointeurs et tableaux
Accéder à une variable pointée

Notion d’un pointeur

Un pointeur est une variable spéciale qui peut contenir l’adresse d’une
autre variable.

Un 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”.

Laila AMIR
Notion d’un pointeur
Introduction
Les opérateurs de base &, *
Les pointeurs
Déclaration d’un pointeur
Pointeurs et fonctions
Initialisation d’un pointeur
Pointeurs et tableaux
Accéder à une variable pointée

Notion d’un pointeur

Remarque :

Il faut faire la différence entre un pointeur et le nom d’une variable :


Un pointeur est une variable qui peut ’pointer’ sur différentes
adresses.
Le nom d’une variable reste toujours lié à la même adresse.

Laila AMIR
Notion d’un pointeur
Introduction
Les opérateurs de base &, *
Les pointeurs
Déclaration d’un pointeur
Pointeurs et fonctions
Initialisation d’un pointeur
Pointeurs et tableaux
Accéder à une variable pointée

Les opérateurs de base

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.
d’une syntaxe de déclaration
pour pouvoir déclarer un pointeur.

Laila AMIR
Notion d’un pointeur
Introduction
Les opérateurs de base &, *
Les pointeurs
Déclaration d’un pointeur
Pointeurs et fonctions
Initialisation d’un pointeur
Pointeurs et tableaux
Accéder à une variable pointée

L’opérateurs : &, *
L’opérateur ’adresse de’ : &
& NomVariable
fournit l’adresse de la variable NomVariable
On a déjà utilisé l’opérateur & dans la fonction scanf, pour désigner
l’adresse de la variable dans laquelle on veut stocker une valeur.
Exemple :
int N;
printf(”Entrez un nombre entier : ”);
scanf(”%d”, &N);
L’opérateur ’contenu de’ : *
* NomPointeur
désigne le contenu de l’adresse référencée par le pointeur NomPointeur
Laila AMIR
Notion d’un pointeur
Introduction
Les opérateurs de base &, *
Les pointeurs
Déclaration d’un pointeur
Pointeurs et fonctions
Initialisation d’un pointeur
Pointeurs et tableaux
Accéder à une variable pointée

Représentation schématique

Alors l’instruction : P = &A;


Soit P un pointeur de type affecte l’adresse de la variable A à la
int non initialisé : variable P.
Nous pouvons illustrer le fait que ’P
pointe sur A’ par une flèche :
=>
et A une variable (du même
type) contenant la valeur 10 :

*P (le contenu de A référencée par P)


vaut 10.

Laila AMIR
Notion d’un pointeur
Introduction
Les opérateurs de base &, *
Les pointeurs
Déclaration d’un pointeur
Pointeurs et fonctions
Initialisation d’un pointeur
Pointeurs et tableaux
Accéder à une variable pointée

Exemple 2

Soit A une variable contenant la valeur 10,

B une variable contenant la valeur 50

et P un pointeur non initialisé.

Laila AMIR
Notion d’un pointeur
Introduction
Les opérateurs de base &, *
Les pointeurs
Déclaration d’un pointeur
Pointeurs et fonctions
Initialisation d’un pointeur
Pointeurs et tableaux
Accéder à une variable pointée

Exemple 2 (suite)

Après les instructions,

P = &A; P pointe sur A,


B = *P; le contenu de A (référencé par *P) est affecté à B,
*P = 20; le contenu de A (référencé par *P) est mis à 20.

=>

Laila AMIR
Notion d’un pointeur
Introduction
Les opérateurs de base &, *
Les pointeurs
Déclaration d’un pointeur
Pointeurs et fonctions
Initialisation d’un pointeur
Pointeurs et tableaux
Accéder à une variable pointée

Déclaration d’un pointeur

Type * NomPointeur;
déclare un pointeur NomPointeur qui peut recevoir des adresses de
variables du type Type.

Le type de variable pointée peut être aussi bien un type primaire


(tel que int, char ...) qu’un type complexe (tel que struct ...).

Il est possible de définir un pointeur sur ’void’, c-à-d sur quelque


chose qui n’a pas de type prédéfini (void * toto). Ce genre de
pointeur sert généralement de pointeur de transition, dans une
fonction générique, avant un transtypage permettant d’accéder
effectivement aux données pointées.
Exemple : int *p1;
Laila AMIR
Notion d’un pointeur
Introduction
Les opérateurs de base &, *
Les pointeurs
Déclaration d’un pointeur
Pointeurs et fonctions
Initialisation d’un pointeur
Pointeurs et tableaux
Accéder à une variable pointée

Initialisation d’un pointeur


Après avoir déclaré un pointeur il faut l’initialiser. Cette démarche est très
importante car lorsque vous déclarez un pointeur, celui-ci risque de pointer
vers une zone hasardeuse de votre mémoire.
Pour initialiser un pointeur, il faut utiliser l’opérateur d’affectation ’=’
suivi de l’opérateur d’adresse ’&’ auquel est accollé un nom de variable
(celle-ci doit bien sûr avoir été définie avant...) :

NomPointeur = &nom-de-la-variable-pointee;

Exemple :
int *p1;
int a = 2;
p1 = &a;

Laila AMIR
Notion d’un pointeur
Introduction
Les opérateurs de base &, *
Les pointeurs
Déclaration d’un pointeur
Pointeurs et fonctions
Initialisation d’un pointeur
Pointeurs et tableaux
Accéder à une variable pointée

Accéder à une variable pointée

Après avoir déclaré et initialisé un pointeur,

il est possible d’accéder au contenu de l’adresse mémoire pointée par le


pointeur grâce à l’opérateur ’*’.

La syntaxe est la suivante : *NomPointeur

Exemple :
int *p1;
int a = 2;
p1 = &a;
*p1 = 10;
Après ces instructions, le contenu de la variable a sera 10.
Laila AMIR
Notion d’un pointeur
Introduction
Les opérateurs de base &, *
Les pointeurs
Déclaration d’un pointeur
Pointeurs et fonctions
Initialisation d’un pointeur
Pointeurs et tableaux
Accéder à une variable pointée

Exemple complet

#include <stdio.h>
int main(){
int a, b, c;
int *x, *y;
a = 98; Exécution :
x = &a;
c = *x + 5; La variable b vaut 108
y = &b; La variable c vaut 103
*y = a + 10;
printf(”La variable b vaut :%d ”, b);
printf(”La variable c vaut :%d”, c);
return 0;
}
Laila AMIR
Notion d’un pointeur
Introduction
Les opérateurs de base &, *
Les pointeurs
Déclaration d’un pointeur
Pointeurs et fonctions
Initialisation d’un pointeur
Pointeurs et tableaux
Accéder à une variable pointée

Explications :
Dans ce programme, on déclare 3 variables a, b et c. On déclare ensuite 2
pointeurs vers des entiers x et y. a est initialisé à 98.
x=&a; permet de mettre dans le un pointeur x l’adresse de a.
*x est la variable pointée par x. a vaut donc 98 après évaluation.
c=*x+5; permet donc de transférer 98+5 donc 103 dans la variable c.
y=&b permet de mettre dans la variable y l’adresse de la variable b. y
est désormais un pointeur vers b.
a+10 vaut 98+10 donc 108.
*y=a+10; permet de transférer dans la variable pointée par y la
valeur de a+10, c’est-à-dire 108. On stocke donc 108 dans b, de
manière indirecte via le pointeur y.
on affiche ensuite les valeurs de b et c c-à-d respect. 108 et 103.

Laila AMIR
Notion d’un pointeur
Introduction
Les opérateurs de base &, *
Les pointeurs
Déclaration d’un pointeur
Pointeurs et fonctions
Initialisation d’un pointeur
Pointeurs et tableaux
Accéder à une variable pointée

Le pointeur NUL

Le mot NULL permet d’initialiser un pointeur qui ne pointe sur rien.


NULL peut être affectée à tout pointeur quel que soit son type.
Exp : int *pn = NULL ;, char *qn = NULL ;

Ce mot est défini dans les librairies stdio.h, stdlib.h.

Dès que l’on déclare un pointeur, il est préférable de l’initialiser à


NULL, surtout dans le cas où l’on ne connait pas sa valeur initiale.

Au moment d’utiliser un pointeur, il est préférable, parfois


indispensable de tester si sa valeur est bien non nulle :
if(pn != NULL)
*pn = ...

Laila AMIR
Introduction
Les pointeurs Portée d’une variable
Pointeurs et fonctions Passage de paramètres par valeur ou par adresse
Pointeurs et tableaux

Outline
1 Introduction
Intérêt des pointeurs
2 Les pointeurs
Notion d’un pointeur
Les opérateurs de base &, *
Déclaration d’un pointeur
Initialisation d’un pointeur
Accéder à une variable pointée
3 Pointeurs et fonctions
Portée d’une variable
Passage de paramètres par valeur ou par adresse
4 Pointeurs et tableaux
Pointeurs et tableaux à une dimension
Pointeurs et tableaux à plusieurs dimensions
Laila AMIR
Introduction
Les pointeurs Portée d’une variable
Pointeurs et fonctions Passage de paramètres par valeur ou par adresse
Pointeurs et tableaux

Variable locale et globale


Variable locale
Les variables dites locales sont celles qui sont déclarés dans un bloc
(délimitees par des accolades { et }, en particulier dans une fonction).
Elles ne sont visibles (donc utilisables) que dans ce bloc.
Leur durée de vie va de l’éxécution de sa déclaration jusqu’à la fin
du bloc.
Variable globale
Ce sont les variables déclarés hors de tout bloc.
Elles sont visibles à partir de leur définition.

Remarque :
Les variables globales déclarés après les includes sont visibles et
modifiables de partout et leur durée de vie celle du programme
=> A manipuler avec précaution (dangereux!).
Laila AMIR
Introduction
Les pointeurs Portée d’une variable
Pointeurs et fonctions Passage de paramètres par valeur ou par adresse
Pointeurs et tableaux

Variable locale et globale


Variable locale
Les variables dites locales sont celles qui sont déclarés dans un bloc
(délimitees par des accolades { et }, en particulier dans une fonction).
Elles ne sont visibles (donc utilisables) que dans ce bloc.
Leur durée de vie va de l’éxécution de sa déclaration jusqu’à la fin
du bloc.
Variable globale
Ce sont les variables déclarés hors de tout bloc.
Elles sont visibles à partir de leur définition.

Remarque :
Les variables globales déclarés après les includes sont visibles et
modifiables de partout et leur durée de vie celle du programme
=> A manipuler avec précaution (dangereux!).
Laila AMIR
Introduction
Les pointeurs Portée d’une variable
Pointeurs et fonctions Passage de paramètres par valeur ou par adresse
Pointeurs et tableaux

Variable locale et globale

Une variable globale peut également être visible dans des fonctions
écrites dans d’autres fichiers sources du programme.
Pour cela, il faut rédeclarer son prototype dans l’autre fichier en
utilisant le mot clé extern.

La portée d’une variable (de visibilité plus large) s’arrete


lorsqu’une variable (de visibilité plus faible) portant le même nom
est déclarée dans un sous-bloc.

Laila AMIR
Introduction
Les pointeurs Portée d’une variable
Pointeurs et fonctions Passage de paramètres par valeur ou par adresse
Pointeurs et tableaux

Exemple
#include <stdio.h>
double x;// Variables globales
int N;
int f1(){
int N; // variable locale masque la variable globale de même nom
int i = 0; // autre variable locale
while(..){
int N; // N locale, masque l’autre N locale & globale
...
}
x = ...; // Utilisation de la variable globale x (déconseillé)
}
int main(){
// dans le main, x et N sont accessibles mais pas i
}
Laila AMIR
Introduction
Les pointeurs Portée d’une variable
Pointeurs et fonctions Passage de paramètres par valeur ou par adresse
Pointeurs et tableaux

Passage de paramètres par valeur ou par adresse

En C, il y a deux méthodes pour passer des variables en paramètre dans


une fonction :

Le passage par valeur;

Le passage par adresse.

Laila AMIR
Introduction
Les pointeurs Portée d’une variable
Pointeurs et fonctions Passage de paramètres par valeur ou par adresse
Pointeurs et tableaux

Passage de paramètres par valeur

En C, le passage des paramètres se fait toujours par la valeur,


c.-à-d. les fonctions n’obtiennent que les valeurs de leurs paramètres
et n’ont pas d’accès aux variables elles-mêmes.

Les paramètres d’une fonction sont à considérer comme des


variables locales qui sont initialisées automatiquement par les
valeurs indiquées lors d’un appel.

A l’intérieur de la fonction, nous pouvons donc changer les valeurs


des paramètres sans influencer les valeurs originales dans les
fonctions appelantes.

Laila AMIR
Introduction
Les pointeurs Portée d’une variable
Pointeurs et fonctions Passage de paramètres par valeur ou par adresse
Pointeurs et tableaux

Exemple : passage de paramètres par valeur

void echange (int a, int b) {


int tmp = a ; // (3)
a=b; // (4)
b = tmp ; // (5)
}
int main () {
int i=10, j=5 ; // (1)
echange (i, j) ; // (2)
printf (”i=%d j=%d\ n”, i, j) ; // (6)
}

Après exécution : i=10 j=5

Laila AMIR
Introduction
Les pointeurs Portée d’une variable
Pointeurs et fonctions Passage de paramètres par valeur ou par adresse
Pointeurs et tableaux

Explication

Lors de l’appel de la fonction echange(), c’est le contenu des variables


i et j qui est copie dans les variables locales a et b.

La fonction echange() échange bien le contenu des variables locales a


et b, mais les valeurs de i et j restent les mêmes..

Laila AMIR
Introduction
Les pointeurs Portée d’une variable
Pointeurs et fonctions Passage de paramètres par valeur ou par adresse
Pointeurs et tableaux

Passage de paramètres par adresse

Comme nous l’avons constaté ci-dessus, une fonction n’obtient que les
valeurs de ses paramètres. Pour changer la valeur d’une variable de la
fonction appelante, nous allons procéder comme suit :

La fonction appelante doit fournir l’adresse de la variable et

La fonction appelée doit déclarer le paramètre comme pointeur.


On peut alors atteindre la variable à l’aide du pointeur.

Laila AMIR
Introduction
Les pointeurs Portée d’une variable
Pointeurs et fonctions Passage de paramètres par valeur ou par adresse
Pointeurs et tableaux

Exemple : passage de paramètres par adresse

void echange (int *a, int *b) {


int tmp = *a ; // (3)
*a = *b ; // (4)
*b = tmp ; // (5)
}
int main () {
int i=10, j=5 ; // (1)
echange (&i, &j) ; // (2)
printf (”i=%d j=%d\ n”, i, j) ; // (6)
}

Après exécution : i=5 j=10

Laila AMIR
Introduction
Les pointeurs Portée d’une variable
Pointeurs et fonctions Passage de paramètres par valeur ou par adresse
Pointeurs et tableaux

Explication

La fonction echange() prend en paramètres deux pointeurs d’entiers


contenant les adresses des variables dont le contenu doit être
échangé.

Lors de l’appel, les adresses de i et de j sont copiées dans les


pointeurs a et b.

La fonction echange() échange ensuite le contenu des adresses


indiquées par les pointeurs a et b.

Laila AMIR
Introduction
Les pointeurs Pointeurs et tableaux à une dimension
Pointeurs et fonctions Pointeurs et tableaux à plusieurs dimensions
Pointeurs et tableaux

Outline
1 Introduction
Intérêt des pointeurs
2 Les pointeurs
Notion d’un pointeur
Les opérateurs de base &, *
Déclaration d’un pointeur
Initialisation d’un pointeur
Accéder à une variable pointée
3 Pointeurs et fonctions
Portée d’une variable
Passage de paramètres par valeur ou par adresse
4 Pointeurs et tableaux
Pointeurs et tableaux à une dimension
Pointeurs et tableaux à plusieurs dimensions
Laila AMIR
Introduction
Les pointeurs Pointeurs et tableaux à une dimension
Pointeurs et fonctions Pointeurs et tableaux à plusieurs dimensions
Pointeurs et tableaux

Pointeurs et tableaux 1D

Il existe une relation très étroite entre tableaux et pointeurs.


Ainsi, chaque opération avec des indices de tableaux peut aussi être
exprimée à l’aide de pointeurs.

Tout tableau en C est en fait un pointeur constant.


Dans la déclaration :
int tab[10];
tab est un pointeur constant (non modifiable) dont la valeur est
l’adresse du premier élément du tableau. Autrement dit, tab a
pour valeur &tab[0].

Laila AMIR
Introduction
Les pointeurs Pointeurs et tableaux à une dimension
Pointeurs et fonctions Pointeurs et tableaux à plusieurs dimensions
Pointeurs et tableaux

On peut donc utiliser un pointeur initialisé à tab.


Exemple :
En déclarant un tableau tab de type int et un pointeur P sur int,
int tab[10];
int *P;

l’instruction: P = tab; est équivalente à P = &tab[0];

Si P pointe sur une composante quelconque d’un tableau, alors P+1


pointe sur la composante suivante. Plus généralement,
P+i pointe sur la i-ième composante derrière P et,
P-i pointe sur la i-ième composante devant P.
Laila AMIR
Introduction
Les pointeurs Pointeurs et tableaux à une dimension
Pointeurs et fonctions Pointeurs et tableaux à plusieurs dimensions
Pointeurs et tableaux

Ainsi, après l’instruction,


P = tab;
Le pointeur P pointe sur tab[0], et
*(P+1) désigne le contenu de tab[1]
*(P+2) désigne le contenu de tab[2]
... ...
*(P+i) désigne le contenu de tab[i]
Attention !
P+i n ’adresse pas le i-ième octet derrière P, mais la i-ième
composante derrière P.
Il y ’a une différence entre un pointeur et le nom d’un tableau :
Un pointeur est une variable, donc des opérations comme P = tab ou
P++ sont permises.
Le nom d’un tableau est une constante, donc des opérations comme
tab = P ou tab++ sont impossibles.
Laila AMIR
Introduction
Les pointeurs Pointeurs et tableaux à une dimension
Pointeurs et fonctions Pointeurs et tableaux à plusieurs dimensions
Pointeurs et tableaux

Résumé

Si tab un tableau d’un type quelconque


et i un indice pour les composantes de tab,
et si P un pointeur de même type

Et si P = tab, alors

P pointe sur l’élément tab[0] &tab[0]


P+i pointe sur l’élément tab[i] &tab[i]
*(P+i) désigne le contenu de tab[i] tab[i]

Laila AMIR
Introduction
Les pointeurs Pointeurs et tableaux à une dimension
Pointeurs et fonctions Pointeurs et tableaux à plusieurs dimensions
Pointeurs et tableaux

parcours des éléments du tableau à l’aide de pointeur

On peut utiliser le pointeur pour parcourir les éléments du tableau :

#define N 5
int tab[5] = {0, 1, 4, 20, 7};
main(){
int *P;
for (P =tab; P < tab+N; P++)
printf(”%d \n”, *P);
}

Laila AMIR
Introduction
Les pointeurs Pointeurs et tableaux à une dimension
Pointeurs et fonctions Pointeurs et tableaux à plusieurs dimensions
Pointeurs et tableaux

Les inconvénients des tableaux

Cependant, la manipulation de tableaux, et non de pointeurs, possède


certains inconvénients dus au fait qu’un tableau est un pointeur constant.
Ainsi :

On ne peut pas créer de tableaux dont la taille est une variable


du programme,

On ne peut pas créer de tableaux bidimensionnels dont les lignes


n ’ont pas toutes le même nombre d’éléments.

Laila AMIR
Introduction
Les pointeurs Pointeurs et tableaux à une dimension
Pointeurs et fonctions Pointeurs et tableaux à plusieurs dimensions
Pointeurs et tableaux

Allocation dynamique 1D avec malloc


Ces opérations deviennent possibles dès que l’on manipule des pointeurs
alloués dynamiquement. Ainsi, pour créer un tableau d’entiers à n
éléments où n est une variable du programme, on écrit :
#include <stdlib.h>
main(){
int n=10;
int *tab;
tab = (int*)malloc(n * sizeof(int));
...
free(tab);
n=5;
tab = (int*)malloc(n * sizeof(int));
...
} free(tab);
Laila AMIR
Introduction
Les pointeurs Pointeurs et tableaux à une dimension
Pointeurs et fonctions Pointeurs et tableaux à plusieurs dimensions
Pointeurs et tableaux

Allocation dynamique 1D avec calloc

Si on veut en plus que tous les éléments du tableau tab soient


initialisés à zéro, on remplace l’allocation dynamique avec malloc par :

tab = (int*)calloc(n, sizeof(int));

Les éléments de tab sont manipulés avec l’opérateur d’indexation [],


exactement comme pour les tableaux.

Laila AMIR
Introduction
Les pointeurs Pointeurs et tableaux à une dimension
Pointeurs et fonctions Pointeurs et tableaux à plusieurs dimensions
Pointeurs et tableaux

Pointeurs et tableaux à plusieurs dimensions

Un tableau à deux dimensions est, par définition, un tableau de


tableaux. Il s ’agit donc en fait d’un pointeur vers un pointeur.

Considérons le tableau à deux dimensions défini par :


int tab[M][N];

tab est un pointeur, qui pointe vers un objet, lui-même de type


pointeur d’entier. tab a une valeur constante égale à l’adresse du
premier élément du tableau, &tab[0][0].

De même tab[i], pour i entre 0 et M-1, est un pointeur constant vers


le premier élément de la ligne d’indice i qui est égale à &tab[i][0].

Laila AMIR
Introduction
Les pointeurs Pointeurs et tableaux à une dimension
Pointeurs et fonctions Pointeurs et tableaux à plusieurs dimensions
Pointeurs et tableaux

Déclaration d’un tableau à plusieurs dimensions

On déclare un pointeur qui pointe sur un objet de type type * (deux


dimensions) de la même manière qu ’un pointeur, c-à-d
type **nom-du-pointeur;

De même, un pointeur qui pointe sur un objet de type type ** (un


tableau à 3 dimensions) se déclare par :
type ***nom-du-pointeur;

Laila AMIR
Introduction
Les pointeurs Pointeurs et tableaux à une dimension
Pointeurs et fonctions Pointeurs et tableaux à plusieurs dimensions
Pointeurs et tableaux

Allocation dynamique d’un tableau à plusieurs dimensions


Par exemple, pour créer avec un pointeur de pointeur une matrice à k
lignes et n colonnes à coefficients entiers, on écrit :
main(){
int k, n;
int **tab;
tab = (int**)malloc(k * sizeof(int*)); //réservation pour
k pointeurs
for (i = 0; i < k; i++) //pour chaque pointeur tab[i]
tab[i] = (int*)malloc(n * sizeof(int)); réservation de l’espace
... mémoire pour n entiers
for (i = 0; i < k; i++)
free(tab[i]);
free(tab);
}
Laila AMIR
Introduction
Les pointeurs Pointeurs et tableaux à une dimension
Pointeurs et fonctions Pointeurs et tableaux à plusieurs dimensions
Pointeurs et tableaux

La première allocation dynamique réserve pour l’objet pointé par tab


l’espace mémoire correspondant à k pointeurs sur des entiers.
Ces k pointeurs correspondent aux lignes de la matrice.

Les allocations dynamiques suivantes réservent pour chaque


pointeur tab[i] l’espace mémoire nécessaire pour stocker n
entiers.

Laila AMIR
Introduction
Les pointeurs Pointeurs et tableaux à une dimension
Pointeurs et fonctions Pointeurs et tableaux à plusieurs dimensions
Pointeurs et tableaux

Si on désire en plus que tous les éléments du tableau soient


initialisés à zéro, il suffit de remplacer l’allocation dynamique dans la
boucle for par :
tab[i] = (int*)calloc(n, sizeof(int));

Contrairement aux tableaux à deux dimensions, on peut choisir des


tailles différentes pour chacune des lignes tab[i]. Par exemple, si
l’on veut que tab[i] contienne exactement i+1 éléments, on écrit :

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


tab[i] = (int*)malloc((i + 1) * sizeof(int));

Laila AMIR