| CHAPITRE
|
APPRENDRE
À PROGRAMMER AVEC FUTUREBASIC
|
NOTES
|
|
Variables III Les pointeurs |
Leçon 6 : Eh
bien ce nest pas trop tôt ! Les pointeurs Dans les 2 leçons précédentes, on a vu les types de variables que nous pouvons manipuler avec nos instructions BASIC, mais, vous vous en doutez ce nest pas encore tout. Lorsque jai commencé à faire de la programmation, je lisais des manuels et jétais quelquefois consterné de ne pas comprendre certains termes que les auteurs assument en général acquis par leurs lecteurs. Cétait exactement le cas pour les pointeurs, et javais fini par imaginer que lorsque ce terme était compris, on pouvait enfin se revendiquer programmeur. Javais donc entouré ce terme dune certaine magie faute de le comprendre. Lorsque ce mystère sest éclairci, jai compris pourquoi les auteurs ne sattardent pas sur ce concept. Il est en effet plutôt simple. Jai pris soin jusquici, de bien faire la distinction entre une variable et son contenu pour que les idées restent bien en place, mais vous verrez quen général, on parlera des variables pour se référer à leur contenu (les valeurs quelles contiennent) ou aux variables elles-mêmes en tant que containers. On a vu précédemment que la variable était un espace en mémoire réservé pour contenir des valeurs qui requièrent plus ou moins doctets. On a vu aussi que cet emplacement en mémoire était en principe fixe et ne changeait pas, seul son contenu pouvait être modifié par nos instructions. Cependant, Il est parfois très utile de connaître ladresse en mémoire dune variable. Les adresses en mémoire peuvent être représentées par des entiers longs (4 octets), pour manipuler ces adresses on utilise un pointeur. Un pointeur nest autre quune variable contenant ladresse dune autre variable. Un pointeur occupe 4 octets en mémoire comme les entiers longs. FutureBASIC dispose dun raccourci que vous rencontrerez très souvent dans des exemples de code pour signifier ladresse dune variable plutôt que son contenu : le symbole @ est utilisé (signifiant at [à] comme dans les adresses e-mail). Par exemple : DIM uneChaine AS STR255 uneChaine = "Je suis une chaîne de caractères" DIM adresseChaine AS POINTER adresseChaine = @uneChaine Notez quen BASIC standard, on écrirait ceci : adresseChaine = VARPTR(uneChaine) Cela revient au même, mais il faut bien lavouer, le symbole @ est bien plus pratique, cest pourquoi nous lutiliserons de préférence à la fonction standard VARPTR qui retourne ladresse de la variable passée en paramètre. Lorsque vous déclarez une variable pointeur, vous pouvez, si vous le souhaitez, indiquer au Compilateur comment il doit interpréter les données rangées à ladresse qui est pointée, en spécifiant un type de variable, par exemple comme ceci : DIM unPointeur AS POINTER TO LONG Notez tout de suite les variantes, plus souvent utilisées pour linstruction ci-dessus : DIM unPointeur AS PTR TO LONG ou DIM unPointeur AS ^LONG Dans linstruction ci-dessus, vous indiquez au Compilateur que ladresse qui sera contenue dans la variable unPointeur sera ladresse dune variable contenant un entier long. Le type que vous indiquez est arbitraire, en réalité FutureBASIC ne vérifie pas si ce que vous écrivez est exact ou non, cest vous qui informez le Compilateur sur la taille de la variable qui se trouve en mémoire à ladresse contenue dans le pointeur. Lorsquon fait ses premiers pas en programmation, on se soucie assez peu de ladresse des variables, en fait, on sintéresse avant tout à leur contenu. Les opérateurs du BASIC, font ce quils ont à faire en nous masquant ce qui se passe réellement, par exemple si lon écrit ceci : x = y Cela revient à assigner une valeur à la variable x. Jusque-là ce nest pas bien sorcier. En réalité, le Compilateur copie le contenu trouvé à ladresse de la variable y vers ladresse de la variable x. Pour nous, cest une façon très simple de changer des données en mémoire, on na pas besoin de savoir où se trouve exactement la variable x, ni la variable y. Vous verrez quil y a des circonstances en programmation où il est parfois commode de pouvoir changer directement les valeurs en mémoire. Le BASIC dispose de commandes pour lire et écrire directement des valeurs à des emplacements en mémoire. PEEK et POKE sont les deux commandes qui respectivement vous permettent de lire ou décrire des valeurs à une adresse en mémoire. Il y a plusieurs variantes et aussi chacune delles dispose dun raccourci avec FutureBASIC. PEEK (ou PEEK BYTE) permet de lire un octet. Raccourci FB : valeurOctet = |adresseMemoire| POKE (ou POKE BYTE) permet décrire un octet. Raccourci : | adresseMemoire,valeurOctet PEEK WORD lit un entier court (2 octets). Raccourci : valeurEntier = {adresseMemoire} POKE WORD écrit un entier court (2 octets). Raccourci : % adresseMemoire,valeurEntier PEEK LONG lit un entier long (4 octets). Raccourci : valeurEntierLong = [adresseMemoire] POKE LONG écrit un entier long (4 octets). Raccourci FB : & adresseMemoire,valeurEntierLong Les programmeurs FutureBASIC utilisent très souvent les raccourcis, aussi, il est bon de les apprendre très rapidement pour comprendre de nombreux morceaux de code que vous serez amené à rencontrer. On a montré précédemment avec deux techniques différentes comment initialiser une variable chaîne avec une chaîne vide : La façon classique en BASIC : DIM uneChaine AS STR255 uneChaine = "" Une façon nouvelle de faire la même chose avec FutureBASIC^3 et sa syntaxe entre crochets : uneChaine[0] = 0 Ci-dessus la valeur 0 est assignée à loctet de longueur, on peut encore faire la même chose en BASIC standard comme ceci : POKE BYTE VARPTR(uneChaine),0 On range un octet de valeur 0 à ladresse de la chaîne (qui est lemplacement en mémoire du premier octet). Et voici, les variations obtenues en utilisant les raccourcis : POKE VARPTR(uneChaine),0 (BYTE est optionnel, lorsquon range un octet) POKE @uneChaine,0 | @uneChaine,0 Les raccourcis ont tendance à rendre le code un peu ésotérique pour les débutants, mais en fait, ils ne sont pas compliqués à mémoriser. Ils sont fréquemment utilisés par les programmeurs FutureBASIC pour deux raisons : souvent le code à taper est plus court (eh oui, parfois la fainéantise a du bon, car elle vous oblige à chercher les méthodes les plus efficaces pour le moindre effort) et très curieusement vous découvrirez que lorsque vous aurez bien assimilé les raccourcis, ils rendront le code plus facile à lire. La deuxième raison est que le code exécutable généré par le Compilateur est un peu plus compact et un peu plus rapide. De nos jours, cela a moins dimportance, les machines sont très rapides et elles disposent de grandes quantités de mémoire, mais vous verrez que dans certaines circonstances, vous aussi, vous rechercherez le maximum de vitesse dans lexécution de vos programmes. Peut-être rejoindrez vous un jour ces programmeurs que l'on rencontre souvent avec FutureBASIC qui s'amusent par goût ou par fierté à se lancer des défis afin de produire du code le plus compact et le plus rapide possible. Dans la plupart des cas, le Compilateur crée les variables en allouant un bloc mémoire de la dimension adéquate lorsquil rencontre une instruction DIM. En nous autorisant laccès aux fonctions de la Toolbox du Macintosh, FutureBASIC^3 nous permet de créer nous-mêmes nos blocs de mémoire comme le fait le Compilateur. Cette opération sexécute en demandant à la Toolbox de créer un pointeur dont on indique la taille. On a cependant, très peu loccasion dutiliser les fonctions relatives aux pointeurs dans la mesure où FutureBASIC se charge très bien des opérations de maintenance par lintermédiaire des variables que nous lui demandons de créer. Une variable pointeur contient donc ladresse dun bloc en mémoire, mais il faut prêter une attention particulière à ce genre de variable, car en accédant directement à la mémoire on travaille sans filet. En effet, rien ne vous empêche de ranger des valeurs à une adresse quelconque en mémoire, si bien que si votre pointeur contient une adresse erronée, la valeur sera inscrite quand même à ladresse indiquée et vous pouvez ainsi modifier par inadvertance des valeurs maintenues dans ces blocs pour dautres variables de votre programme, ce qui donne souvent des résultats inattendus et des erreurs difficiles à corriger comme des blocages du programme sur des instructions innocentes, ou pire encore, si vous accédez à des zones mémoire réservées à dautres applications ou même au Système, vous serez très susceptible dexpérimenter un crash de la machine. Un deuxième inconvénient survient lorsquon crée soi-même ses pointeurs pour y stocker des valeurs au gré de ses besoins, car les blocs de mémoire que vous réservez ne sont pas rendus disponibles automatiquement une fois que votre code nen a plus lutilité et si lon ne sen débarrasse pas explicitement, ils finissent par saturer la mémoire inutilement. On est donc obligé de faire soi-même le ménage, en demandant au Memory Manager de libérer la mémoire occupée par les pointeurs devenus inutiles aux besoins du programme. Non seulement cette maintenance est nécessaire, mais la mémoire est utilisée moins efficacement à cause de la fragmentation engendrée lors de la libération des blocs de mémoire. Nous reviendrons ultérieurement sur le Memory Manager et l'importance de son travail. [Precédent] [Table des Matières] [Suivant] |
{Note} |
|
FutureBASIC est une marque déposée appartenant à Staz Software, Inc et utilisée avec permission. |
||