LOCODUINO

Aide
Forum de discussion
Dépôt GIT Locoduino
Flux RSS

mardi 19 mars 2024

Visiteurs connectés : 13

Les pointeurs (2)

Suite et fin

.
Par : Thierry

DIFFICULTÉ :

Après les simples pointeurs, voyons des usages plus rares, mais toujours aussi puissants...

<

Les poupées Russes : les pointeurs de pointeur.

Un pointeur est en réalité un entier qui représente une adresse, mais c’est avant tout un entier. Et la conséquence immédiate de cette observation, c’est que tout ce qui est applicable à un entier l’est aussi à un pointeur. En particulier les opérations arithmétiques, comme on l’a vu précédemment. Cet entier a aussi besoin d’occuper un espace mémoire pour stocker sa valeur. On retombe sur le contenant et le contenu ! L’adresse d’un pointeur est un pointeur, et son contenu est une adresse

int val = 123;
int *pVal = &val;
int **ppVal = &pVal;
int ***pppVal = &ppVal;

Serial.println(val, DEC);   // Affiche 123
Serial.println(*pVal, DEC);   // Affiche 123 aussi !
Serial.println(**ppVal, DEC);   // Affiche 123 aussi !!
Serial.println(***pppVal, DEC);   // Affiche 123 aussi !!!

Et ainsi de suite... Le nombre d’étoiles devant le nom détermine la profondeur du pointeur. pppVal est un pointeur de pointeur de pointeur d’entier ! Le contenu de pppVal est un pointeur. Le contenu de *pppVal est encore un pointeur . Le contenu de **pppVal est encore (encore !) un pointeur. Enfin le contenu de ***pppVal est bien l’entier !
Et vous allez me dire, "mais à quoi ça sert ?", et vous aurez raison de poser la question. Prenons un cas simple. Je veux allouer une zone de mémoire, et modifier un pointeur passé en argument d’une fonction :

void Allocate(int **ppTableau, int size)
{
  *ppTableau = new int[size];
}

setup()
{
int *pTableau;

Allocate(&pTableau, 100);
...
}

Je passe ainsi l’adresse de mon pointeur pTableau comme argument de type int ** (pointeur de pointeur d’entier). L’allocation se fait par un new qui remplit le contenu de ce pointeur. Une étoile en moins donne le contenu de l’argument. A la fin du setup, le pointeur pTableau a bien été alloué de 100 entiers.

Encore pire : les pointeurs de fonction

On a vu que toutes les données nécessitant un contenu, types de base, tableaux, structures, classes sont adressées par un pointeur. Même si aucune donnée n’est transportée, les fonctions sont aussi des pointeurs. Elles ne représentent pas une adresse dans la SRAM puisqu’il n’y a aucun contenu, mais ce sont des adresses dans la mémoire Flash. Il est ainsi possible de stocker une adresse de fonction, de la passer en argument, et d’appeler la fonction qui est derrière ce pointeur.

Déclaration d’un pointeur de fonction

Un pointeur de fonction est différent d’un entier. Il doit tenir compte de la signature de la fonction à pointer. C’est à dire que le type de retour et les arguments doivent être rigoureusement les mêmes pour que le pointeur accepte de stocker l’adresse. Il faut donc déclarer le format de ce pointeur :

byte (*pFonction)(int argument);

Cette ligne précise que le pointeur nommé pFonction peut être l’adresse d’une fonction dont le type de retour est un byte, et doit posséder un argument entier.
L’affectation est toute simple :

int fonction(int value)
{
   // fait des choses avec la valeur...
   return 128;
}

byte (*pFonction)(int val);

setup()
{
  pFunction = &fonction;
}

pFunction contient l’adresse de fonction. Reste à utiliser le pointeur pour appeler la fonction :

if ( (*pFunction) (10) > 64)
  ...

Mais alors...

Ceux qui ont suivi les articles sur Le Monde des Objets ont peut être fait le rapprochement. Lorsqu’une fonction est virtuelle, c’est à dire qu’elle peut être redéfinie dans une classe dérivée, c’est un pointeur de fonction qui est utilisé...

Et maintenant...

Que vais je faire ? C’est plutôt à vous de vous poser la question. Le domaine des pointeurs est très vaste. C’est une notion très puissante et très pratique, mais elle est aussi difficile à appréhender pour les non informaticiens. Vous trouverez sur le Net quantité de tutoriaux sur le sujet. et tout ce qui est applicable au langage C est transposable à l’Arduino.

Réagissez à « Les pointeurs (2) »

Qui êtes-vous ?
Votre message

Pour créer des paragraphes, laissez simplement des lignes vides.

Lien hypertexte

(Si votre message se réfère à un article publié sur le Web, ou à une page fournissant plus d’informations, vous pouvez indiquer ci-après le titre de la page et son adresse.)

Rubrique « Programmation »

Le monde des objets (1)

Le monde des objets (2)

Le monde des objets (3)

Le monde des objets (4)

Les Timers (I)

Les Timers (II)

Les Timers (III)

Les Timers (IV)

Les Timers (V)

Bien utiliser l’IDE d’Arduino (1)

Bien utiliser l’IDE d’Arduino (2)

Piloter son Arduino avec son navigateur web et Node.js (1)

Piloter son Arduino avec son navigateur web et Node.js (2)

Piloter son Arduino avec son navigateur web et Node.js (3)

Piloter son Arduino avec son navigateur web et Node.js (4)

Comment gérer le temps dans un programme ?

La programmation, qu’est ce que c’est

Types, constantes et variables

Installation de l’IDE Arduino

Répéter des instructions : les boucles

Les interruptions (1)

Instructions conditionnelles : le if ... else

Instructions conditionnelles : le switch ... case

Comment concevoir rationnellement votre système

Comment gérer l’aléatoire ?

Calculer avec l’Arduino (1)

Calculer avec l’Arduino (2)

Les structures

Systèmes de numération

Les fonctions

Trois façons de déclarer des constantes

Transcription d’un programme simple en programmation objet

Ces tableaux qui peuvent nous simplifier le développement Arduino

Les chaînes de caractères

Trucs, astuces et choses à ne pas faire !

Processing pour nos trains

Arduino : toute première fois !

Démarrer en Processing (1)

TCOs en Processing (1)

TCOs en Processing (2)

L’assembleur (1)

L’assembleur (2)

L’assembleur (3)

L’assembleur (4)

L’assembleur (5)

L’assembleur (6)

L’assembleur (7)

L’assembleur (8)

L’assembleur (9)

Les derniers articles

L’assembleur (9)


Christian

L’assembleur (8)


Christian

L’assembleur (7)


Christian

L’assembleur (6)


Christian

L’assembleur (5)


Christian

L’assembleur (4)


Christian

L’assembleur (3)


Christian

L’assembleur (2)


Christian

L’assembleur (1)


Christian

TCOs en Processing (2)


Pierre59

Les articles les plus lus

Les Timers (I)

Les interruptions (1)

Instructions conditionnelles : le if ... else

Bien utiliser l’IDE d’Arduino (1)

Comment gérer le temps dans un programme ?

Ces tableaux qui peuvent nous simplifier le développement Arduino

Les structures

Les Timers (III)

Les Timers (II)

Trois façons de déclarer des constantes