4D v16.3Pointeurs |
||||||||||||||||||||||||||||||||
|
4D v16.3
Pointeurs
Pointeurs
Les pointeurs sont des outils de programmation avancée. Lorsque vous utilisez le langage de 4D, vous vous référez aux différents objets par l’intermédiaire de leur nom — en particulier les tables, champs, variables et tableaux. Pour appeler l’un d’entre eux, vous écrivez simplement son nom. Cependant, il est parfois utile de pouvoir appeler ou référencer ces éléments sans nécessairement connaître leur nom. C’est ce que permettent les pointeurs. Le concept de pointeur n’est pas tellement éloigné de la vie courante. Vous vous référez souvent à des choses sans connaître leur identité exacte. Par exemple, vous dites à un ami “Allons-y avec ta voiture” au lieu de “Allons-y avec la voiture immatriculée 123 ABD 99”. Dans ce cas, vous faites référence à la voiture immatriculée 123 ABD 99 en utilisant l’expression “ta voiture”. Par analogie, l’expression “la voiture immatriculée 123 ABD 99” est le nom d’un objet, et “ta voiture” est un pointeur référençant (ou pointant vers) l’objet. La capacité de se référer à quelque chose sans connaître son identité exacte est très utile. Si votre ami s’achetait une nouvelle voiture, l’expression “ta voiture” serait toujours exacte — ce serait toujours une voiture et vous pourriez toujours aller quelque part avec. Les pointeurs fonctionnent de la même manière. Par exemple, un pointeur peut pointer à un moment donné vers un champ numérique appelé Age, et plus tard vers une variable numérique appelée Ancien âge. Dans les deux cas, le pointeur référence des données numériques pouvant être utilisée dans des calculs. Vous pouvez utiliser des pointeurs pour référencer des tables, des champs, des variables, des tableaux et des éléments de tableaux. Le tableau suivant vous fournit un exemple de chaque type :
Il est plus facile d’expliquer l’utilisation des pointeurs au travers d’un exemple. Cet exemple vous montre comment accéder à une variable par l’intermédiaire d’un pointeur. Nous commençons par créer la variable : MaVar:="Bonjour" MaVar est désormais une variable contenant la chaîne “Bonjour”. Nous pouvons alors créer un pointeur vers MaVar : MonPointeur:=->MaVar Le symbole -> signifie “pointer vers” (ce symbole est formé du caractère “tiret” (-) suivi du caractère “supérieur à”). Dans ce cas, il crée un pointeur qui référence ou “pointe vers” MaVar. Ce pointeur est assigné à MonPointeur via l’opérateur d’assignation. MonPointeur est désormais une variable qui contient un pointeur vers MaVar. MonPointeur ne contient pas “Bonjour”, la valeur de MaVar, mais vous pouvez utiliser MonPointeur pour obtenir la valeur contenue dans MaVar. L’expression suivante retourne la valeur de MaVar : MonPointeur-> Dans ce cas, la chaîne “Bonjour” est retournée. Lorsque le symbole -> est placé derrière un pointeur, la valeur de l’objet vers lequel pointe le pointeur est récupérée. On dit alors qu’on dépointe le pointeur. Il est important de comprendre que vous pouvez utiliser un pointeur suivi du symbole -> partout où vous auriez pu utiliser l’objet pointé lui-même. Vous pouvez placer l’expression MonPointeur-> partout où vous pourriez utiliser la variable originale MaVar. Par exemple, l'instruction suivante affiche une boîte de dialogue d’alerte comportant le mot Bonjour : ALERT(MonPointeur->) Vous pouvez également utiliser MonPointeur pour modifier la valeur de MaVar. Par exemple, l’instruction suivante stocke la chaîne “Au revoir” dans la variable MaVar : MonPointeur->:="Au revoir" Si vous examinez les deux utilisations de l’expression MonPointeur-> ci-dessus, vous constatez que cette expression se comporte exactement comme si vous aviez utilisé MaVar à sa place. En résumé : les deux lignes suivantes effectuent la même opération — elles affichent une boîte de dialogue d’alerte contenant la valeur courante de la variable MaVar : ALERT(MonPointeur->) Les deux lignes suivantes effectuent la même opération ; elles assignent la chaîne "Au revoir" à MaVar : MonPointeur->:="Au revoir" Ce paragraphe décrit l’utilisation d’un pointeur pour référencer un bouton. Un bouton (du point de vue du langage) n’est rien d’autre qu’une variable. Bien que les exemples de ce paragraphe utilisent des pointeurs pour référencer des boutons, les concepts présentés s’appliquent à l’utilisation de tout type d’objet pouvant être référencé par un pointeur. Imaginons que vous disposiez dans vos formulaires d’un certain nombre de boutons devant être actifs ou inactifs. Chaque bouton est associé à une condition qui peut être VRAI ou FAUX. La condition indique s’il faut désactiver ou activer le bouton. Vous pouvez utiliser un test comme celui-ci chaque fois que vous devez désactiver ou activer le bouton : If(Condition) ` Si la condition est VRAIE… Vous pouvez avoir besoin, pour chaque bouton que vous avez créé, d’utiliser un test similaire, dans lequel seul le nom du bouton change. Afin d’être plus efficace, vous pouvez créer un pointeur pour référencer chaque bouton puis utiliser une sous-routine pour le test lui-même. Vous devez utiliser des pointeurs si vous appelez une sous-routine, car il n’est pas possible de faire référence autrement aux variables des boutons. Par exemple, voici une méthode projet nommée FIXER_BOUTON, qui référence un bouton avec un pointeur : ` Méthode projet FIXER_BOUTON Vous pouvez appeler la méthode projet FIXER_BOUTON de la manière suivante : ` ... Partout où le langage requiert un nom de table, vous pouvez utiliser un pointeur dépointé vers une table. TablePtr:=->[touteTable] Vous pouvez également récupérer un pointeur vers une table à l’aide de la fonction Table. Par exemple : TablePtr:=Table(20) Vous pouvez utiliser le pointeur dépointé dans vos commandes, comme ceci : DEFAULT TABLE(TablePtr->) Partout où le langage requiert un nom de champ, vous pouvez utiliser un pointeur dépointé vers un champ. ChampPtr:=->[uneTable]CeChamp Vous pouvez également récupérer un pointeur vers un champ à l’aide de la fonction Field. Par exemple : ChampPtr:=Field(1;2) Vous pouvez utiliser le pointeur dépointé avec les commandes, comme ceci : OBJECT SET FONT(ChampPtr->;"Arial") L'exemple fourni au début de cette section illustre l'utilisation d'un pointeur vers une variable : MaVar:="Bonjour" ` Création de la variable MaVar Vous pouvez faire pointer des pointeurs vers des variables interprocess, process et, à compter de la version 2004.1 de 4D, vers des variables locales. Lorsque vous utilisez des pointeurs vers des variables locales ou des variables process, vous devez veiller à ce que la variable pointée soit bien définie au moment de l’utilisation du pointeur. Rappelons que les variables locales sont supprimées à la fin de l’exécution de la méthode qui les a créées et les variables process à la fin du process dans lequel elles ont été créées. L’appel d’un pointeur vers une variable qui n’existe plus provoque une erreur de syntaxe en mode interprété (variable indéfinie) mais peut générer une erreur plus conséquente en mode compilé. Note sur les variables locales : Les pointeurs vers des variables locales permettent dans de nombreux cas d’économiser des variables process. Les pointeurs vers des variables locales peuvent être utilisés uniquement à l’intérieur d’un même process. $MaVar:="Bonjour" Dans Méthode2, le débogueur affichera $1 de la façon suivante :
La valeur de $1 sera :
Vous pouvez créer un pointeur vers un élément de tableau. Par exemple, les lignes d'instruction suivantes créent un tableau et assignent à une variable appelée ElémPtr un pointeur vers le premier élément : ARRAY REAL(unTableau;10) ` Créer un tableau Vous pouvez alors utiliser le pointeur dépointé pour assigner une valeur à l’élément, comme ceci : ElémPtr->:=8 Vous pouvez créer un pointeur vers un tableau. Par exemple, les lignes d'instruction suivantes créent un tableau et assignent à la variable nommée TabPtr un pointeur vers le tableau : ARRAY REAL(unTableau;10) ` Créer un tableau Il est important de comprendre que ce pointeur pointe vers le tableau, et non vers un élément du tableau. Par exemple, vous pourriez utiliser le pointeur dépointé de la manière suivante : SORT ARRAY(TabPtr->;>) ` Tri du tableau Si vous devez vous référer au quatrième élément du tableau à l’aide du pointeur, vous pouvez écrire : TabPtr->{4}:=84 Il est souvent utile de disposer d’un tableau de pointeurs référençant un groupe d’objets homogène. Un exemple d'utilisation typique d’un tel groupe d’objets est une grille de variables dans un formulaire. Chaque variable dans la grille est numérotée de manière séquentielle, par exemple : Var1, Var2,…, Var10. Vous devez souvent vous référer à ces variables, de manière indirecte — par leur numéro. Si vous créez un tableau de pointeurs et faites pointer les pointeurs vers chaque variable, il est alors facile de référencer les variables. Par exemple, pour créer un tableau et initialiser chaque élément, vous pouvez écrire : ARRAY POINTER(tabPointeurs;10) ` Créer un tableau de 10 pointeurs La fonction Get pointer retourne un pointeur vers l'objet passé en paramètre. Pour référencer une des variables, il suffit d’appeler les éléments du tableau. Par exemple, pour remplir les variables avec les dix prochains jours (en supposant que les variables soient de type Date), vous pourriez écrire : For($i;1;10) ` Boucle une fois par variable Si vous disposez d’un groupe homogène de boutons radio dans un formulaire, vous devrez souvent pouvoir définir rapidement leur état. La solution consistant à référencer chacun d’entre eux par son nom n’est pas très pratique. Imaginons que vous disposiez d'un groupe de cinq boutons radio libellés Bouton1, Bouton2,…, Bouton5. Dans un groupe de boutons radio, seul l’un d’entre eux est sélectionné. Le numéro du bouton sélectionné peut être stocké dans un champ numérique. Par exemple, si le champ [Préférences]EtatBouton contient 3, alors Bouton3 est sélectionné. Dans la méthode formulaire, vous pouvez utiliser le code suivant pour paramétrer les boutons : Case of Un cas particulier doit être testé pour chaque bouton radio. La méthode peut être très longue si le formulaire contient de nombreux boutons radio. Heureusement, vous pouvez utiliser des pointeurs pour résoudre ce problème. Case of Le numéro du bouton radio traité doit être stocké dans le champ [Préférences]EtatBouton. Cette opération peut être effectuée dans la méthode formulaire, pour l'événement formulaire Sur clic : [Préférences]EtatBouton:=Bouton1+(Bouton2*2)+(Bouton3*3)+(Bouton4*4)+(Bouton5*5) Vous pouvez passer un pointeur en tant que paramètre d’une méthode. A l’intérieur de la méthode, vous pouvez modifier l’objet référencé par le pointeur. Par exemple, la méthode suivante, RECOIT DEUX, reçoit deux paramètres qui sont des pointeurs. Elle passe l’objet référencé par le premier paramètre en caractères majuscules, et l’objet référencé par le second paramètre en caractères minuscules : ` Méthode projet RECOIT DEUX L'instruction suivante emploie la méthode RECOIT DEUX pour passer un champ en caractères majuscules et une variable en caractères minuscules : RECOIT DEUX(->[MaTable]MonChamp;->MaVar) Si le champ, [MaTable]MonChamp, contenait la chaîne "dupont", celle-ci deviendrait "DUPONT". Si la variable MaVar contenait la chaîne "BONJOUR", celle-ci deviendrait "bonjour". Dans la méthode RECOIT DEUX (et, en fait, à chaque fois que vous utilisez des pointeurs), il est important que les types de données des objets référencés soient corrects. Dans l’exemple précédent, les pointeurs doivent pointer vers des objets contenant une chaîne ou un texte. Si vous aimez compliquer les choses à l'extrême (bien que cela ne soit pas nécessaire dans 4D), vous pouvez utiliser des pointeurs pour référencer d'autres pointeurs. Examinons l’exemple suivant : MaVar:="Bonjour" Cet exemple affiche une boîte de dialogue d’alerte contenant “Au revoir”. Voici la description de chaque ligne de l’exemple :
La ligne suivante place la valeur "Bonjour" dans MaVar : (PointeurDeux->)->:="Bonjour" La ligne suivante récupère "Bonjour" à partir de MaVar et la place dans NouvelleVar : NouvelleVar:=(PointeurDeux->)-> Important : Vous devez utiliser des parenthèses lors des déréférencements multiples.
Voir aussi
Conditions et boucles
|
PROPRIÉTÉS
Produit : 4D
HISTORIQUE
UTILISATION DE L'ARTICLE
4D - Langage ( 4D v16) |
||||||||||||||||||||||||||||||