| CHAPITRE
|
APPRENDRE
À PROGRAMMER AVEC FUTUREBASIC
|
NOTES
|
||||
|
Les Variables II |
Leçon 5 : Eh bien on nest
pas arrivé ! Limportant nest pas daller vite en besogne, mais sachez que lassimilation des bases vous fera avancer ultérieurement à pas de géants. En général, les leçons dinformatique débutent très vite par un petit programme pour gratifier lapprenti et lencourager à persévérer. Pour sacrifier à la tradition, choisissez le Runtime Console par lintermédiaire du menu Commande et tapez la ligne suivante dans léditeur : PRINT "Je suis devenu(e) une bête en programmation." Voilà, cest fait ! vous pouvez exécuter votre programme (article Exécuter "Sans titre 1" du menu Commande) ou bien en faire une réelle application Macintosh (article Construire du menu Commande) après avoir sauvegardé votre fichier de code source sur votre disque dur. Pour linstant, le but que nous poursuivons nest pas dexpliquer les commandes, ce quelles font et comment les exploiter au mieux, mais il sagit de comprendre ou plutôt de se faire une représentation des rouages internes qui sont mis en action. Lorsque cette image sest formée, lensemble devient très cohérent et chaque chose tient bien en place. Pour résumer, quavons-nous appris jusque-là ? Dans le texte que nous rédigeons (le code source) nous utilisons des noms symboliques pour représenter des valeurs que nous manipulerons avec des instructions composées de commandes ou de fonctions et dopérateurs. Pour les valeurs qui restent fixes tout au long du programme nous sommes avisés quil vaut mieux déclarer des constantes portant un nom significatif afin de faciliter la compréhension du code source, tandis que les valeurs qui sont susceptibles de changer seront stockées dans des variables. Les variables occupent plus ou moins de cases en mémoire suivant les valeurs quon doit y ranger. Les valeurs quon y range sont des octets (des suites de 8 bits) que le Compilateur saura correctement manipuler si on lui indique le type de la variable concernée. Voici enfin un exemple concret : _bonus = 10 DIM AS SHORT x, y x = -4 y = ABS(x) - _bonus x, y et bonus sont des noms symboliques. x et y sont des variables tandis que _bonus est une constante nommée. Linstruction _bonus = 10 assigne à la constante la valeur quelle représentera tout au long du programme (dans ce programme _bonus vaudra tout le temps 10). Linstruction DIM AS SHORT x,y indique au Compilateur que les variables x et y vont contenir des valeurs entières (chacune dentre elles occupera deux octets qui pourront représenter des valeurs allant de 32768 à +32767) Linstruction x = -4 range la valeur -4 dans la variable quon a choisie dappeler x. La troisième instruction est un peu plus compliquée : dans la variable y sera rangé le résultat dun calcul. Comme précédemment indiqué, le signe égal est lopérateur dassignation du BASIC. La variable qui doit être assignée se trouve toujours à la gauche du signe égal, tandis que la valeur à ranger est à la droite de ce même signe. On emploiera fréquemment le terme « expression numérique » lorsque la partie droite fournit le résultat dun calcul. Ici, lopération effectuée est une soustraction; vous avez sans doute remarqué lopérateur - devant la constante _bonus. Les expressions numériques peuvent devenir très compliquées parce quelles peuvent inclure des appels à des fonctions qui font elles-mêmes des calculs et retournent un résultat. Cest le cas ici, avec ABS qui est une fonction standard du BASIC. Cette fonction accepte un seul paramètre et retourne une valeur. ABS retourne la valeur absolue du nombre que vous lui passez en paramètre. Si vous lui passez 7 par exemple, elle vous retournera 7, et si vous lui passez -7 elle vous retournera 7 aussi. Dans notre exemple cest le contenu de la variable x qui est passé en paramètre à la fonction ABS, et x valant -4 la valeur retournée par la fonction sera donc 4. Le calcul effectué par linstruction se résumera finalement à ceci : y = 4 - 10 y se verra donc assigner la valeur -6. Les fractionnaires Pour représenter le monde correctement les entiers ne sont pas suffisants, et très souvent on a besoin dune plus grande précision. FB propose trois types de variables pour représenter des nombres qui peuvent avoir une partie décimale et une partie fractionnaire. Nous nentrerons pas maintenant dans le détail de lorganisation interne des octets, mais chacun des types diffère par la quantité de mémoire quil nécessite, la plage des valeurs quil peut représenter et sa précision. Le type FIXED est assez peu utilisé, il occupe 4 octets de stockage et peut représenter des valeurs dans la plage 32767.99998 à +32767.99998, il est précis jusquà 5 chiffres après la virgule. Une variable de type FIXED a ceci de particulier quelle ne possède pas de suffixe identificateur de type, en conséquence, vous ne pouvez déclarer ce type de variable quà laide de la commande DIM suivie de la clause AS FIXED. Notez dès à présent que les nombres utilisés par le langage sont au format anglo-saxon. Ce que nous appelons la virgule sécrit avec un point. Nous serions tentés décrire ceci par exemple : x = 10,3 FB ne comprendra pas ce que vous voulez faire, pour lui, la virgule a une autre signification comme séparer les arguments dune fonction par exemple. Dans votre code source, vous devrez écrire ceci à la place : x = 10.3 Pour nous français, il y a là une difficulté que lon apprend vite à maîtriser. La difficulté survient lorsquon veut afficher ce type de valeurs, car nous devons bien sûr reformater le nombre en remplaçant le point par une virgule avant de le présenter sur l'écran à lutilisateur final de notre application. La difficulté est double, car une conversion similaire doit être opérée dans la direction inverse lorsque les valeurs nous sont fournies par lutilisateur ou bien proviennent dun fichier externe à notre application. Cependant cette tâche nous sera facilitée à la fois par FutureBASIC et par la Toolbox du Macintosh, mais nous ne nous attarderons pas sur ce problème maintenant. Les nombres fractionnaires sont le plus souvent représentés avec les types SINGLE (simple précision, suffixe !) et DOUBLE (double précision, suffixe #). On dit que ce sont des nombres à virgule flottante, car le point décimal nest pas fixe. Le type DOUBLE est plus précis et peut représenter une plus grande plage de valeurs que le type SINGLE, mais aussi il occupe une plus grande place de stockage en mémoire. Le type SINGLE occupe 4 octets en mémoire tandis que le type DOUBLE possède une étrange particularité : son espace de stockage varie suivant le processeur pour lequel vous compilez votre programme. Lorsque vous compilez pour le 68K (ancien processeur qui équipaient les machines dApple) il occupe 8 octets, lorsque vous compilez pour le PowerPC, il en occupe 10. Comme on le voit, sur le PowerPC 80 bits sont utilisés pour représenter un nombre. Nous ne rentrerons pas ici dans le détail de larrangement interne des bits, mais il na plus rien à voir avec ce qui a été montré concernant les nombres entiers. Les chaînes Le type chaîne (suffixe identificateur $) est utilisé pour représenter une suite de caractères. Le nombre maximum de caractères dune variable de ce type est 255. Cela ne vous rappelle-t-il rien ? Et en effet, cest bien la valeur maximale que lon peut obtenir avec un octet non signé. Comprendre lorganisation interne simplissime dune chaîne vous sera utile en de nombreuses occasions. Une chaîne se présente en mémoire comme une suite doctets. Le premier octet indique le nombre de caractères dont la chaîne est constituée, et ce premier octet est suivi par les caractères en question. Mais quest-ce à dire, je croyais que lon ne stockait en mémoire que des 1 et des 0, comment peut-on alors avoir des caractères ? On a commencé à voir peu à peu que lorganisation interne des valeurs, des octets et des bits navait que peu de choses à voir avec ce que lêtre humain perçoit et croit manipuler. En réalité, les caractères nexistent pas en eux-mêmes, la suite doctets dans une chaîne nest finalement quune suite de nombres. En fait, notre alphabet a été codifié et à chaque symbole a été attribué une valeur unique représentable avec un octet non signé, et on dispose dune table de correspondance. Par exemple, la valeur 65 a été attribuée à la lettre A (notez la majuscule), 66 à la lettre B, etc. Ces codes sont appelés codes ASCII. Heureusement, il nest pas nécessaire de connaître la table des codes ASCII pour manipuler des chaînes de caractères. Sachez toutefois que seuls les premiers 127 éléments de cette table ont été standardisés (les codes et ce quils représentent sont identiques sur le Macintosh comme sur le PC, mais au-delà de 127 cela nest plus vrai). Pour se faire une petite idée, imaginez une variable chaîne contenant le texte "Bonjour", pour l'ordinateur ce n'est qu'une suite de bits, ou si vous préférez de 1 et de 0 quelque part en mémoire: 0000011101000010011011110110111001101010011011110111010101110010 Chaque groupe de 8 bits forme un octet dont on peut se figurer la représentation décimale à l'aide des puissances de 2 comme précédemment montré : 7 66 111 110 106 111 117 114 La première valeur est 7 et elle correspond bien au nombre de caractères contenus dans notre chaîne. Bonjour a autant de lettres qu'il y a de jours dans la semaine. Le deuxième octet vaut 66 et représente le code ASCII de la lettre B majuscule; 111 et le code ASCII pour la lettre o minuscule; 110 pour la lettre n minuscule; etc.
Une chaîne nest donc quun octet de longueur suivi du code ASCII des caractères qui la composent. Cet arrangement des octets est appelé chaîne Pascal (du langage de programmation appelé Pascal). Dautres langages nauront pas nécessairement la même façon de représenter une chaîne de caractères. Par exemple, le langage C ne connaît pas loctet de longueur ; pour ce langage, une chaîne nest que la suite des codes ASCII des caractères terminée par le caractère nul (dont le code ASCII vaut zéro). Les chaînes du C, ne sont pas limitées à 255 caractères. On peut assigner une variable chaîne de la façon suivante: DIM chaine AS STR255 chaine = "Je suis une chaîne de caractères" Le texte placé entre guillemets deviendra le contenu de la variable. Le BASIC fournit des fonctions spécialisées pour manipuler les chaînes de caractères, nous les verrons plus loin, mais sachez dès maintenant que le seul opérateur utilisable avec deux variables de type chaîne à lexception de lassignation est laddition. Lopération qui consiste à ajouter deux chaînes pour en former une nouvelle est connue sous le nom de concaténation. _espace$ = " " DIM AS STR255 nom, prenom, patronyme prenom = "Dominique" nom = "Lebrun" patronyme = "Votre patronyme :" + _espace$ + nom + _espace$ + prenom Une fois la dernière instruction du programme ci-dessus exécutée, la variable patronyme contiendra la chaîne de caractères suivante : Votre patronyme : Lebrun Dominique. Là encore vous devez bien saisir la distinction entre la variable et son contenu : lorsque vous déclarez une variable de type chaîne, un espace est réservé en mémoire par le Compilateur pour contenir les caractères éventuels qui la composeront. Un octet de longueur suivi de 255 octets possibles cela fait au total 256 octets. Même une chaîne vide (avec 0 caractère) occupera la même place en mémoire. Vous le constatez, les chaînes sont plus gourmandes en mémoire que les nombres, car dans le même espace on pourrait loger 64 entiers longs (qui occupent 4 octets chacun) ou encore 128 entiers courts. FutureBASIC^3 a introduit dans le langage une nouvelle syntaxe inspirée des langages C et Pascal qui traitent les chaînes comme des tableaux de caractères. Auparavant, comme il a déjà été mentionné, on devait utiliser des fonctions spécialisées pour manipuler les chaînes, mais désormais, cette nouvelle syntaxe nous permet dexaminer et de modifier individuellement les caractères dune chaîne. Par exemple pour connaître le code ASCII du troisième caractère contenu dans une variable chaîne (appelée ci-dessous laChaine) vous pourrez utiliser les crochets : codeASCII = laChaine[3] Habituellement, en BASIC, pour connaître la longueur dune chaîne, cest-à-dire le nombre de caractères qui la composent, on utilise la fonction LEN qui est très souvent sollicitée : longueurChaine = LEN(laChaine) Ci-dessus, le résultat de la fonction LEN est stocké dans la variable longueurChaine, mais là encore la syntaxe entre crochets peut être mise à profit en écrivant ceci à la place : longueurChaine = laChaine[0] Le premier octet dune chaîne Pascal est loctet de longueur indiquant le nombre de caractères quelle contient. Lindice 0 entre crochets, nous permet dexaminer cet octet. Vous pouvez également assigner les caractères ainsi que la longueur de la chaîne individuellement grâce à cette syntaxe, par exemple : laChaine[0] = 0 Linstruction ci-dessus assigne à la variable une chaîne de 0 caractère de longueur, cest donc une chaîne vide. Léquivalent en BASIC traditionnel serait linstruction suivante : laChaine = "" Linstruction qui suit : laChaine[3] = 65 assigne le code ASCII 65 (qui correspond à la lettre A majuscule) au troisième caractère contenu dans la variable appelée laChaine. Cest ici loccasion de présenter une facilité décriture fort appréciable proposée par FutureBASIC. Vous pouvez retrouver le code ASCII dun caractère grâce à la syntaxe montrée ci-dessous: _"A" vaut 65 _"B" vaut 66 etc. Lexemple précédent peut donc sécrire dune manière plus compréhensible par un être humain, aussi il ne faut pas se priver de cette particularité : laChaine[3] = _"A" En BASIC standard, vous écririez pour la même opération: MID$(laChaine,3) = "A" Mais il faut noter que les instructions ont tendance à devenir plus difficiles à lire en BASIC traditionnel quand plusieurs fonctions traitant des chaînes sont imbriquées dans une même expression. Par ailleurs, la syntaxe entre crochets produit un code compilé plus compact et plus rapide à l'exécution. On vient de voir que la longueur maximale dune chaîne de caractères ne pouvait excéder 255, il faut donc prêter une attention particulière lorsque lon concatène des chaînes pour ne pas dépasser ce maximum autorisé. Très fréquemment, on na pas besoin dautant doctets pour mémoriser de linformation, par exemple pour contenir le nom dun fichier (sur le Macintosh un nom de fichier ne pouvait dépasser 31 caractères jusquà larrivée du nouveau système de fichiers HFS+, où ce nombre est passé à 255, il faut signaler toutefois que la plupart des applications, y compris le Finder dans Mac OS 9, ne gèrent pas encore cet état de fait !), FB^3 propose plusieurs types de chaînes qui diffèrent par leur possibilité de stockage : STR15, STR31, STR63, STR255. Vous avez sans doute remarqué que les tailles utilisées sont des nombres impairs ; en réalité, le nombre indique la quantité maximale de caractères que lon pourra stocker dans une variable de ce type, mais pour connaître la quantité de mémoire effectivement occupée, il faut ajouter à ce chiffre loctet de longueur, si bien que lespace réellement occupé est toujours un nombre pair doctets. Ce nest pas un hasard, car lordinateur travaille beaucoup plus efficacement lorsque les variables sont alignées en mémoire sur des adresses paires. Sachez aussi que vous pouvez réserver une quantité arbitraire doctets (ne dépassant pas 255) lors de la déclaration dune chaîne de caractères en utilisant la syntaxe comme montrée dans linstruction suivante : DIM 7 uneChaine$ Notez que le nombre de caractères est placé juste avant le nom de la variable chaîne que vous voulez déclarer et que ce nom doit avoir le suffixe identificateur de type approprié aux chaînes. Linstruction ci-dessus réserve donc 7 octets pour les éventuels caractères, plus 1 octet de longueur, cela fait 8 octets au total. Lalignement des variables sur une frontière paire sera correct. Maintenant, si vous écrivez ceci : DIM 8 uneChaine$ vous réservez 8 octets pour les caractères et 1 octet de longueur, le total nous donne 9, un chiffre impair. FutureBASIC, dans cette situation, ajoutera un octet pour que la frontière entre les variables soit toujours une valeur paire. 10 octets seront alors effectivement réservés. On appelle cet invité surprise un octet dalignement. Si dans limmense majorité des cas vous naurez jamais à vous soucier de ce détail interne, il pourra arriver quil prenne de limportance en de rares occasions. Les variables composées ou records Jusquici les choses ne sont pas trop compliquées, nous navons parlé que de quelques types fondamentaux avec lesquels on peut déjà faire beaucoup de choses, certes, mais très vite lorsquon programme, on réalise que ces types de variables ne sont pas suffisants pour décrire des éléments quon souhaite manipuler. Un exemple simple est le rectangle : pour décrire un rectangle on aura besoin de 4 coordonnées les coordonnées x,y du point situé en haut à gauche et celles du point situé en bas à droite. On peut très bien sarranger en créant 4 variables : x1, y1, x2 et y2. Des entiers courts sont généralement suffisants pour y ranger les valeurs quon veut y stocker. 4 entiers courts de 2 octets chacun, cela nous fait 8 octets de stockage. Il serait bien pratique davoir ces 8 octets placés consécutivement en mémoire et de nous référer au rectangle au moyen dune seule variable. Cest exactement de que font les records. Les records (connus sous le nom de structures dans dautres langages) sont un agrégat de variables qui ne sont dailleurs pas toute forcément du même type. Ces variables sont donc regroupées sous une même entité. Les records permettent ainsi au programmeur de créer ses propres types de variables. La définition dun type de record est très simple, examinez comment on pourrait définir un type de variable Rectangle : BEGIN RECORD Rectangle DIM y1 AS SHORT DIM x1 AS SHORT DIM y2 AS SHORT DIM x2 AS SHORT END RECORD La commande BEGIN RECORD vous permet de donner un nom à votre structure, tandis que la commande END RECORD termine la définition. Entre ces deux commandes, vous déclarez des variables avec leur type de la même manière quil a été montré jusque là. Rien de plus simple, mais en réalité il ne faut pas sy tromper, les diverses déclarations à lintérieur de la structure ne sont pas des déclarations de variables en tant que telles. En fait, ici vous déclarez ce quon appelle des champs. Donc, les champs dun record se déclarent de la même manière que des variables. Comme les variables, les champs dun record portent un nom qui les identifie et possèdent un type indiquant la quantité de stockage mémoire pour les valeurs quils sont amenés à contenir. Une fois que votre structure est définie, vous pouvez déclarer des variables possédant ce type. Par exemple : DIM rect1 AS Rectangle DIM rect2 AS Rectangle Les instructions ci-dessus déclarent deux variables (rect1 et rect2) comme étant du type Rectangle. Pour manipuler les valeurs contenues dans ces variables, vous utiliserez le nom des champs (notez le point qui sépare le nom de la variable, du nom du champ) : rect1.x1 = 0 La valeur 0 est rangée dans le champ x1 de la variable rect1 rect2.x1 = rect1.x1 + 50 Le champ x1 de la variable rect2 recevra la valeur du champ x1 de la variable rect1 additionnée de 50. Définir un record revient en fait à définir un type de variable qui peut être composé avec dautres types préexistants. Un record peut contenir des champs de différents types y compris des champs qui sont eux-mêmes des records. Exemple : BEGIN RECORD Objet DIM epaisseur AS INT DIM contour AS Rectangle END RECORD Pour accéder à une valeur contenue dans le champ contour qui est aussi un record, on pourrait avoir ceci : DIM unObjet AS Objet x = unObjet.contour.x1 Notez les points qui séparent les champs. Lespace de stockage pour une variable de ce type est la somme des espaces de stockage de tous les champs qui le composent. Dans lexemple ci-dessus, la variable unObjet occuperait la place en mémoire de 6 entiers courts soit 12 octets au total. Dans FB^3 les records définis par BEGIN RECORD/END RECORD sont appelés vrais records. FB considère la structure comme un type de variable à part entière. On verra quil nen est pas de même pour les pseudo records. Une fois que vous avez défini une structure, vous pouvez bien sûr dimensionner autant de variables de ce type que votre programme le nécessite. À linstar des constantes, les records doivent pouvoir être identifiés de manière unique par le Compilateur. Cest pourquoi vous ne pouvez avoir deux records portant le même nom dans un même programme. Cependant, vous pouvez avoir plusieurs records différents qui possèdent des champs portant le même nom. Par exemple, vous ne pouvez pas avoir ceci : BEGIN RECORD Objet DIM epaisseur AS INT DIM contour AS Rectangle END RECORD BEGIN RECORD Objet DIM couleur AS INT DIM largeur AS INT DIM hauteur AS INT END RECORD Le Compilateur ne saurait pas quelle définition utiliser pour dimensionner une variable de type Objet, aussi refusera-t-il de compiler votre programme si vous commettez cette erreur. Mais, vous pourriez avoir ceci : BEGIN RECORD Objet DIM epaisseur AS INT DIM contour   AS Rectangle END RECORD BEGIN RECORD Cadre DIM contour AS Rectangle DIM epaisseur AS LONG END RECORD Deux vrais records différents peuvent avoir des champs dont les noms sont identiques et qui peuvent représenter des valeurs de types différents. Dans les anciens BASIC, les structures nexistaient pas, on était condamné à déclarer des variables séparées et à les gérer individuellement. Vous trouverez encore beaucoup de morceaux de code écrits pour FutureBASIC qui nen font pas usage, mais vous verrez très vite que les structures sont vraiment très commodes pour organiser les données à lintérieur de vos programmes. FutureBASIC agit intelligemment avec les records, par exemple si vous avez deux variables records de la même longueur (occupant la même place en mémoire) vous pouvez assigner en une seule opération le contenu dune variable record à une autre. DIM AS Objet obj1, obj2 obj1 = obj2 Ci-dessus, le contenu de obj2 est copié dans obj1 quelle que soit la taille requise pour les variables de type Objet. Toutefois, vous ne pouvez pas comparer des variables records entre elles, vous devrez comparer chaque champ de la première variable au champ correspondant de la seconde. Il faut savoir que les fonctions et les procédures de la Toolbox du Macintosh font un usage très intensif des structures. Cest pourquoi il est bon de se familiariser assez vite avec ce concept. La Toolbox déclare donc une quantité impressionnante de records, et pour sa part, FutureBASIC déclare pour vous ceux qui sont le plus fréquemment utilisés. Par exemple, la structure pour un rectangle est déjà définie comme ceci par la Toolbox : BEGIN RECORD Rect DIM top AS INT DIM left AS INT DIM bottom AS INT DIM right AS INT END RECORD Du fait que FutureBASIC définit pour vous un tel record, vous pouvez déclarer une variable de ce type et accéder à ses champs sans avoir plus de travail à fournir. Exemple : DIM monRectangle AS RECT monRectangle.top = 10 monRectangle.left = 10 monRectangle.bottom = 50 monRectangle.right = 50 Si vous tentiez de définir la structure RECT dans votre code source, le Compilateur ne manquerait pas de se plaindre en vous signalant que vous essayez de dupliquer une définition. Rien ne vous empêche cependant de définir un record identique et de lutiliser partout dans votre code où un record RECT est attendu, par exemple : BEGIN RECORD Rectangle DIM haut AS INT DIM gauche AS INT DIM bas AS INT DIM droite AS INT END RECORD On verra plus loin, dautres avantages à utiliser des vrais records pour ses programmes. Les vrais records comme décrits ci-dessus sont apparus avec FutureBASIC^3, mais historiquement, FutureBASIC utilisait des records différents. Beaucoup de programmeurs continuent à utiliser les anciens records, on ne chasse pas aussi vite les habitudes quon prend en programmation, c'est d'ailleurs pourquoi il est bon d'en prendre de bonnes dès le départ. Il est probable que ces structures, appelées aujourdhui pseudo records, disparaîtront progressivement au profit des vrais records. Les pseudo records sont un peu plus délicats à maintenir. Un pseudo record peut être déclaré de la manière suivante : DIM RECORD Objet DIM epaisseur AS INT DIM contour AS RECT DIM END RECORD .tailleObjet Lorsque le Compilateur rencontre une telle déclaration dans votre code source, il ne va pas créer un type de variable spécifique et par conséquent vous ne pourrez pas déclarer une variable du type de cette structure avec linstruction suivante : DIM monObjet AS Objet Le Compilateur se plaindra en vous signalant que le type pour cette variable na pas encore été défini. Mais alors que fait le Compilateur exactement ? Il va analyser votre déclaration et en déduire des constantes. Les constantes sont créées en fonction du nom des champs et du stockage réservé pour chaque champ. Si nous prenons lexemple déjà mentionné, après analyse du Compilateur nous aurions : _epaisseur = 0 _contour = 2 _tailleObjet = 6 La valeur des constantes générées correspond au décalage du champ (en octets) par rapport au début de la structure. Le champ epaisseur étant le premier champ, il se confond avec le début de la structure, il ny a donc aucun décalage à opérer pour accéder au champ, doù la valeur 0 attribuée à la constante _epaisseur. En revanche pour accéder au champ contour, les deux octets de stockage (entier court) du champ epaisseur doivent être sautés, cest pourquoi la constante _contour se voit attribuer la valeur 2. Si nous avions introduit un autre champ après le champ contour, par exemple, un champ appelé couleur pouvant stocker un entier court, nous aurions alors _couleur = 2 (octets pour epaisseur) + 8 (octets pour contour 4 X 2 entiers courts pour une structure RECT), soit : _couleur = 10. La dernière constante créée, _tailleObjet, est le total en octets de lespace de stockage pour la structure entière. On déclare une variable de ce type de la manière suivante: DIM monObjet.tailleObjet Lorsque vous déclarez une variable comme ci-dessus, le Compilateur va simplement réserver un espace de stockage en mémoire dont la taille correspondra à la constante _tailleObjet. Bien que le code soit plus lisible ainsi, notez quil nest pas obligatoire dutiliser la constante générée par FutureBASIC et vous auriez pu aussi bien écrire ceci : DIM monObjet.6 Et lon accède aux champs de la manière suivante comme avec les vrais records : monObjet.epaisseur = 10 monObjet.contour.left = 20 monObjet.contour.top = 20 monObjet.contour.right = 100 monObjet.contour.bottom = 200 Il y a une petite subtilité quil est bon de connaître : si vous utilisez un caractère de soulignement à la place dun point dans linstruction DIM END RECORD, non seulement le Compilateur générera les constantes comme précédemment expliqué, mais aussi il déclarera une variable unique correspondant à cette structure et dont le nom sera le nom du record. DIM RECORD Objet DIM epaisseur AS INT DIM contour AS RECT DIM END RECORD _tailleObjet Objet.epaisseur = 10 La variable Objet a été gracieusement créée pour nous par le Compilateur, du fait que nous avons utilisé un caractère de soulignement à la place du point dans linstruction DIM END RECORD. Si vous avez suivi jusque-là, vous constaterez que le bout de code suivant : DIM RECORD Objet DIM epaisseur AS INT DIM contour AS RECT DIM END RECORD .tailleObjet DIM monObjet.tailleObjet Est en pratique équivalent à écrire ceci : _epaisseur = 0 _contour = 2 _tailleObjet = 6 DIM monObjet.tailleObjet Vous pouvez bien sûr utiliser lune ou lautre forme dans vos programmes. Ceci nous montre deux choses cependant : le typage des variables à laide de pseudo records est un typage très faible, il sagit essentiellement dune génération de constantes symboliques présentée un peu différemment et le deuxième point en découle, car rappelez-vous que les constantes doivent pouvoir être identifiées de manière unique par le Compilateur, ce qui revient à dire que vous ne pourrez pas avoir deux pseudo records ayant des champs portant le même nom et que vous ne pourrez pas utiliser non plus des noms déjà réservés pour les constantes prédéfinies par FutureBASIC. Les vrais records nont pas cette limitation. Enfin, pour être complet, il faut signaler lexistence dune forme spéciale décriture sapparentant à la déclaration de records. Cette forme spéciale assez rarement utilisée, est obtenue en faisant appel au recouvrement (ou chevauchement) de variables. Examinez linstruction suivante : DIM monRectangle.8;0,haut AS INT,gauche AS INT,bas AS INT,droite AS INT Vous avez noté le point-virgule suivi du zéro ? Que fait le Compilateur lorsquil rencontre une telle instruction ? Linstruction DIM lui indique quil doit déclarer des variables. Vous demandez au Compilateur de créer la variable monRectangle qui requiert 8 octets de stockage (monRectangle.8), jusque-là rien de spécial. Le point-virgule suivi du 0 indique au Compilateur de ne pas tenir compte des 8 octets de stockage lorsquil va créer les variables suivantes si bien que la variable dénommée haut sera déclarée en mémoire à la même adresse que la variable monRectangle. En réalité, à laide du point-virgule, on indique un décalage (compté en octets) par rapport à ladresse de la variable à laquelle il est rattaché (un autre chiffre aurait pu être utilisé à la place de 0). Lorsque 0 est utilisé, les variables monRectangle et haut partagent la même adresse en mémoire. |monRectangle;0---------------------------------------------------------| |haut-------------|gauche-----------|bas--------------|droite-----------| |××××××××|××××××××|××××××××|××××××××|××××××××|××××××××|××××××××|××××××××| |monRectangle;2---------------------------------------------------------| |-----------------|haut-------------|gauche-----------|bas--------------|droite-----------| |××××××××|××××××××|××××××××|××××××××|××××××××|××××××××|××××××××|××××××××|××××××××|××××××××| Lillustration ci-dessus montre comment on peut se figurer la mémoire avec un décalage de 0, puis un décalage de 2 octets. Les losanges représentent les bits, les groupes de 8 losanges sont séparés entre eux par une barre verticale pour représenter des octets (groupes de 8 bits). Les noms des variables sont aussi séparés entre eux par une barre verticale pour représenter létendue en espace de stockage de chaque variable (un entier court occupe 2 octets). Le recouvrement de variables permet essentiellement une facilité décriture dans le code. Certaines fonctions de la Toolbox du Macintosh sattendent à recevoir une structure en paramètre et plutôt que de créer une variable record et daccéder à ses champs, quelques programmeurs préfèrent utiliser la technique du recouvrement pour manipuler les champs directement au moyen de variables. Examinez lexemple suivant : DIM monRectangle AS RECT;0,haut AS INT,gauche AS INT,¬ bas AS INT,droite AS INT haut = 10 gauche = 10 bas = 100 droite = 100 est équivalent à lécriture plus traditionnelle, montrée ci-dessous : DIM monRectangle AS RECT monRectangle.top = 10 monRectangle.left = 10 monRectangle.bottom = 100 monRectangle.right = 100 Notez également que vous pouvez imbriquer des recouvrements et réaliser des structures relativement complexes. Lécriture ultérieure du code est donc simplifiée avec le recouvrement des variables, mais cette technique a aussi ses inconvénients qui peuvent faire surface si lon demande au Compilateur daligner les variables en mémoire sur des frontières adaptées à leur type. Ceci est un peu technique, mais lalignement des variables permet au processeur de travailler plus efficacement et plus rapidement. Encore une fois, la technique du recouvrement nest pas très répandue, elle est mentionnée ici, à titre indicatif. [Precédent] [Table des Matières] [Suivant] |
Codes
ASCII non-standards Aujourdhui, nous assistons à lémergence dune autre codification, appelée UNICODE qui a lavantage, non seulement de faire une vraie place aux lettres accentuées qui parcourent notre langue, mais aussi aux signes, accents, et caractères spéciaux présents dans les autres langues européennes et dailleurs. |
|
FutureBASIC est une marque déposée appartenant à Staz Software, Inc et utilisée avec permission. |
||