Les Pointeurs en langage C - Programmation Maroc

 Programmation Maroc

le chemin vers la programmation

Programmation Maroc

mercredi 27 mai 2020

Les Pointeurs en langage C

                           

                                            ***  Les Pointeurs  ***

1) Introduction   
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, c’est-à-dire. à l'aide de variables auxquelles on peut attribuer les adresses d'autres variables. 

En C, les pointeurs jouent un rôle principal  dans la définition de fonctions: Comme 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. Ainsi le traitement de tableaux et de chaînes de caractères dans des fonctions serait impossible sans l'utilisation de pointeurs.
En outre, les pointeurs nous permettent d'écrire des programmes plus compacts et plus efficace et fournissent souvent la seule solution raisonnable à un problème. Ainsi, la majorité des applications écrites en C profitent extensivement des pointeurs.

 2) Adressage de variables 
Avant de parler de pointeurs, il est indiqué brièvement  les deux modes d'adressage principaux, qui vont d'ailleurs nous accompagner tout au long des chapitres suivants.

2-1) 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 de l'ordinateur. Le nom de la variable nous permet alors d'accéder directement à cette valeur.

 Exemple:     Int  A=12 ;






2-2) Adressage indirect
Si nous ne voulons ou ne pouvons pas utiliser le nom d'une variable A, nous pouvons copier l'adresse de cette variable dans une variable spéciale P, appelée pointeur. Ensuite, nous pouvons retrouver l'information de la variable A en passant par le pointeur P. ce dernier contient l'adresse de variable A.

Exemple : 
Soit A une variable contenant la valeur 10  et  P un pointeur qui contient l'adresse de A. En mémoire, A et P peuvent se présenter comme suit:

 








 3) Les pointeurs 

Un pointeur est une variable spéciale qui peut contenir l'adresse d'une autre variable En 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.

Remarque :
Les pointeurs et les noms de variables ont le même rôle: Ils donnent accès à un emplacement dans la mémoire interne de l'ordinateur. Il faut quand même bien faire la différence:
*Un pointeur est une variable qui peut "pointer" sur différentes adresses
*Le nom d'une variable reste toujours lié à la même adresse

2-1) Les opérateurs de base 

Lors du travail avec des pointeurs, nous avons besion
==> 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'un syntaxe de déclaration : pour déclarer un pointeur.

L'opérateur "adresse de" :    & NomVariable    permet de fournir  l'adresse de la variable  NomVariable

Exemple :

p  = &A ; cette instruction  permet  d’affecter  l’adresse de variable A  à  la variable p.







&A :  signifie l’adresse  de variable A (E0H5),  et aussi le contenu de variable  p.

printf(" l’adresse de A est %d ", p) ;    ou         printf("l’adresse de A est %d ", &A) ;

Le message qui va afficher sur l’écran est  ceci :   l’adresse de A est  E0H5 .


L'opérateur "contenu de":   * <NomVariable>    désigne le contenu de l'adresse référencée par le pointeur <NomPointeur>.
Exemple :

*p : signifie le contenu de l'adresse référencée par le pointeur, dans ce cas-là  c’est la valeur de variable A  (10).

printf("le contenu de A est %d ", A) ;   ou      printf("le contenu de A est %d ", *p) ;

Le message qui va afficher sur l’écran est  ceci :  le contenu de A est : 10.

Déclaration d'un pointeur : 
Type  *  NomPointeur  ;   

Cette instruction permet de déclarer  un pointeur <NomPointeur> qui peut recevoir des adresses de variables du  type  <Type>.

Exemples :           int * P ;                float * P ; 

Exemple d’application





























 4) Pointeurs et tableaux

4-1) introduction                                                                           

En C, 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. En général, les versions formulées avec des pointeurs sont plus compactes et plus efficientes, surtout à l'intérieur de fonctions. Mais, du moins pour des débutants, le 'formalisme pointeur' est un peu inhabituel .

4-2) Adressage des éléments  d'un tableau 
On définit le  nom d'un tableau  comme  l'adresse de son premier élément. En d’autres termes:  &tableau[0] et tableau    sont une seule et même adresse.
En simplifiant, nous pouvons retenir que le nom d'un tableau est un pointeur constant sur le premier élément du tableau.
Exemple :








Pour obtenir l’adresse du premier  élément  du tableau:
==> L’expression  tableau  signifie l’adresse du premier élément du tableau, alors elle contient 8767
==> L’expression  &tableau [0] signifie l’adresse du premier élément du tableau, c’est-à-dire  8767 

Pour obtenir  l’adresse du  deuxième élément  du tableau  on incrémente   par  1
==L’expression  tableau +1  signifie l’adresse du deuxième  élément du tableau, c’est-à-dire  8768
==>  L’expression  &tableau [1] signifie l’adresse du premier élément du tableau, c’est-à-dire  8768

Pour obtenir  l’adresse du  i ème  élément du tableau 
==> L’expression  tableau + i  signifie l’adresse du deuxième  élément du tableau, c’est-à-dire  8767 + i
==> L’expression  &tableau [i] signifie l’adresse du premier élément du tableau, c’est-à-dire  8767 + i 

Pour obtenir la  valeur  du premier élément  du tableau


 ==L’expression * tableau  signifie  la valeur du premier élément du tableau, alors elle contient  5

 ==L’expression  &tableau [0] signifie la valeur  du premier élément du tableau, c’est-à-dire  5

Pour obtenir  la valeur  du  deuxième élément  du tableau, on incrémente   par  1 
 ==>  L’expression *(tableau +1)  signifie l’adresse du deuxième  élément du tableau, c’est-à-dire  2
==L’expression  tableau [1] signifie l’adresse du premier élément du tableau, c’est-à-dire  2

En résume :
Le nom d'un tableau est un pointeur constant sur le premier élément du tableau. 
Les deux expressions &tableau[0] et tableau    sont  équivalents.

Exercice  d’application
Ecrire un programme  permettant de saisir  5 entiers  et de les stocker dans un tableau nommé  tableau, puis les afficher.  (NB. utiliser la notion de pointeur !!!!) 























Exercice 1
Soit P un pointeur qui 'pointe' sur un tableau A:
int A[] = {12, 23, 34, 45, 56, 67, 78, 89, 90};
int *P;     P = A;
Quelles valeurs ou adresses fournissent ces expressions:

a)    *P+2 
b)    *(P+2)     
c)    &P+1 
d)    &A[4]-3    
e)    A+3        
f)    1+(*P-10)  
g)    *(P + *(P+8)-A[7])

 solution 

a) 14
b) 34
c) l’adresse du 2éme élement du tableau
d) l’adresse du 2éme élement du tableau
e) l’adresse du 4éme élement du tableau
f) 3
g) 23

Exercice 2
Ecrire un programme qui range les éléments d'un tableau A du type int dans l'ordre inverse. Le programme utilisera des pointeurs P1 et P2 et une variable numérique AIDE pour la permutation des éléments.




























Aucun commentaire:

Publier un commentaire