Obligement - L'Amiga au maximum

Samedi 27 mai 2017 - 15:51  

Translate

En De Nl Nl
Es Pt It Nl


Rubriques

 · Accueil
 · A Propos
 · Articles
 · Galeries
 · Glossaire
 · Hit Parade
 · Liens
 · Liste jeux Amiga
 · Quizz
 · Téléchargements
 · Trucs et astuces


Articles

 · Actualité (récente)
 · Actualité (archive)
 · Comparatifs
 · Dossiers
 · Entrevues
 · Matériel (tests)
 · Matériel (bidouilles)
 · Points de vue
 · En pratique
 · Programmation
 · Reportages
 · Tests de jeux
 · Tests de logiciels
 · Tests de compilations
 · Articles divers

 · Articles in english
 · Articles in other languages


Twitter

Suivez-nous sur Twitter




Liens

 · Sites de téléchargements
 · Associations
 · Pages Personnelles
 · Moteurs de recherche
 · Pages de liens
 · Constructeurs matériels
 · Matériel
 · Autres sites de matériel
 · Réparateurs
 · Revendeurs
 · Presse et médias
 · Programmation
 · Développeurs logiciels
 · Logiciels
 · Développeurs de jeux
 · Jeux
 · Autres sites de jeux
 · Scène démo
 · Divers
 · Informatique générale


Jeux Amiga

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Trucs et astuces

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Glossaire

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Partenaires

Annuaire Amiga

Amedia Computer

Relec

Hit Parade


Soutien

N'hésitez pas à soutenir le projet Obligement



Contact

David Brunet

Courriel

 


Programmation : Amiga E - la mémoire et les pointeurs
(Article écrit par Yann Armand et Pierre Girard et extrait d'Amiga News - octobre 1995)


Nous devinons votre frustration à la lecture de l'article précédant. En effet, le traitement des arguments n'était pas expliqué, mais les pages d'Amiga News ne sont pas extensibles à l'infini. Réparons donc cette infamie à travers l'explication de la mémoire et des pointeurs.

La mémoire

Comme tous ses homologues à puces, l'Amiga (et non pas le chien) possède une mémoire (le chien aussi, c'est vrai). Celle-ci est essentielle car elle permet d'exploiter aussi bien les programmes que les données. En ce qui nous concerne, elle sert essentiellement à stocker temporairement les données que nous manipulons.

La mémoire est constituée de cases mémoire repérées par une adresse. Elle peut être comparée à un gros livre dont chaque page serait une case mémoire, le numéro de la page étant son adresse.

Son utilisation première reste, dans notre cas, la variable. En effet, cette dernière n'est autre qu'une case mémoire dans laquelle il est possible de stocker du texte (STRING), des entiers (INT), etc. En fait, une variable n'est qu'un nom que le compilateur comprendra comme une adresse numérique qu'il transmettra au microprocesseur. Comme nous sentons que ce n'est pas très clair dans votre esprit, voici un petit exemple :

/* Adresse et contenu d'une variable */
DEF var
PROC main()
    var:=3
    WriteF('l''adresse de var est : \d\n',{var})
    WriteF('var contient : \d\n',var)
ENDPROC

var est une variable INT (entier) dans laquelle nous stockons 3. Son adresse pour le microprocesseur est notée en langage E: {var}.

Les pointeurs

Les pointeurs sont des variables dans lesquelles, au lieu de stocker des informations, nous stockons des adresses numériques compréhensibles par le microprocesseur. Acoissacerdonc ? Ceux-ci nous seront très utiles pour l'utilisation des fonctions du système qui ne raisonnent que sur des adresses, comme par exemple ReadArgs() que nous avons rencontré le mois dernier. Petit exemple :

/* Utilisation d'un pointeur */
DEF chaine[30]:STRING
DEF p:PTR TO INT
PROC main()
    chaine:='Ceci est une chaîne'
    p:={chaine}
    WriteF('l''adresse de chaine 
                        est: \d\n',{chaine})
    WriteF('p pointe sur l''adresse : \d\n',p)
    WriteF('le contenu de la case pointée 
                        par p est : \d\n',^p)
ENDPROC

"chaine" est une variable de type STRING (chaîne de caractères) à laquelle nous affectons la valeur 'Ceci est une chaîne'.

"p" est un pointeur auquel nous affectons l'adresse de "chaine". Nous avons donc un pointeur p qui pointe sur une chaîne de caractères. La valeur de p est l'adresse à laquelle se trouve la chaîne de caractères. Pour accéder au contenu de l'adresse pointée par un pointeur, il faut utiliser le symbole ^ suivi du nom du pointeur. Ainsi ^p représente le contenu de la chaîne de caractères "chaine" ('Ceci est une chaîne').

Pointeurs et Objects

Comme nous l'avons vu dans le premier article, nous pouvons rassembler plusieurs variables en une seule par l'intermédiaire des Objets. Reprenons l'exemple de notre bibliothèque de CD :

OBJECT cd
    nom[50]:STRING      /* nom du cd */
    durée:INT           /* durée en min */
    plages:INT          /* nb de plages */
ENDOBJECT

Nous avons créé un type CD, et à chaque fois que nous affectons ce type à une variable :

DEF metallica:cd

Nous créons en fait un pointeur sur une zone mémoire qui contient toutes les variables définies dans l'objet. Pour accéder à celles-ci, nous utilisons un adressage dit relatif de la forme : nom du pointeur.nom de la variable. Exemple : metallica.nom.

Que cache cette syntaxe ? Le compilateur dit au processeur de manipuler la variable "nom", d'un objet CD, à partir du pointeur metallica. Vous voulez un exemple d'utilisation ? Très bien. Imaginons que nous possédons un tableau (mescd[]) constitué de la liste des pointeurs sur les CD de notre audiothèque. Nous créons un pointeur (pcd) qui pourra pointer sur un objet de type CD :

    DEF pcd:PTR TO cd

Pour connaître le nom du troisième CD de la liste, il nous suffit d'écrire :

    pcd:=mescd[3]
    WriteF('nom du cd:\s\n',pcd.nom)

Nous affectons à pcd le 3e élément du tableau de pointeur sur les CD (pcd[3]), et nous écrivons à l'écran le nom du cd (pcd.nom).

Le programme ReadArgs

Étant donné que nous avons décrit en détail les pointeurs, nous ne nous attarderons pas sur la partie du programme qui y fait référence. Tout notre programme se trouve dans la procédure main(), mais rien ne vous empêche d'en faire une procédure générique que vous pourrez inclure dans vos programmes personnels.

Après les définitions de i et de rdargs qui nous permettrons de gérer les boucles et de lancer la fonction ReadArgs(), nous définissons result qui est un pointeur sur un mot long et args qui est un tableau de 32 mots longs (pointeurs). La première boucle sert à initialiser (mise à zéro) les 32 arguments. La partie principale du programme se trouve à l'intérieur d'un test qui vérifie que la fonction ReadArgs() renvoie bien une structure rdargs. Il convient maintenant de nous attarder sur cette fonction de la bibliothèque DOS.

Le langage E peut très bien gérer les arguments, alors pourquoi utiliser la fonction de la dos.library ? Cette fonction est bien plus puissante que la gestion des arguments par le E. Elle permet de définir les arguments souhaités (texte, nombres...) ainsi que leur modificateurs (traduction française de "modifiers") qui peuvent être /S (switch), /K (keyword), /N (number), /T (toggle), /A (Required), /F (Rest of line), /M (multiple strings).

De plus, ReadArgs() renvoie un pointeur pour chaque information alors que la variable arg du E ne retourne qu'une chaîne de caractères qu'il faut ensuite traiter. Nous vous conseillons de vous référer aux Autodocs pour de plus amples informations sur cette fonction (et les autres !).

Revenons au programme. Nous appelons la fonction ReadArgs() avec comme paramètres une chaîne de formatage et le tableau de mots longs pour récupérer le résultat. Si vous avez compris les modificateurs, vous vous apercevez que nous désirons récupérer des arguments dont les quatre premiers sont des nombres et les suivants des chaînes de caractères. A noter que seul le premier argument est obligatoire (/A). Si l'utilisateur entre au clavier un mauvais argument (par exemple, un nombre à la place d'une chaîne de caractères), la fonction ReadArgs() renvoie un code d'erreur et notre programme affiche alors la ligne d'usage.

Le reste du programme se charge uniquement d'afficher les arguments avec tout d'abord dans la première boucle les quatre nombres (de 0 à 3) dont nous allons rechercher la valeur à l'aide du signe ^ vu plus haut. C'est un peu plus compliqué pour les chaînes de caractères suivantes, étant donné que nous ne savons pas combien il y en a. La fonction ReadArgs() nous renvoie l'adresse d'un tableau de pointeurs sur les différentes chaînes de caractères. Il faut, dans ce cas, tester si l'on arrive en fin de tableau (pointeur nul) avec une instruction WHILE. Une fois le programme terminé, il convient de rendre la mémoire allouée par la fonction ReadArgs() pour sa structure (rdargs) et cela à l'aide la fonction FreeArgs(rdargs).

Voilà, nous pensons avoir à peu près fait le tour de la question. C'est promis, le mois prochain, on essaye de faire un peu plus concret. Il serait intéressant que vous écriviez au journal pour nous faire part de vos impressions et pour nous aiguiller quant à nos articles futurs. Atchao, bonsoir.

 /* Exemple de lecture d'arguments */
PROC main()
    DEF rdargs,i,result:PTR TO LONG
    DEF args[32]:ARRAY OF LONG      /* 32 arguments au maximum */

    FOR i:= 0 TO 31 
            /* initialisation du tableau de pointeur des arguments */
        args[i]:=0
    ENDFOR
    IF rdargs:=ReadArgs('/N/A,/N,/N,/N,/M',args,NIL)
        FOR i:=0 TO 3
            result:=args[i]         
            /* chaque entrée du tableau pointe sur un nombre */
            WriteF('argument n°:\d =\d\n',1+i,^result) 
            /* ^result va chercher la valeur pointée par le tableau */
        ENDFOR
        i:=0
        result:=args[4] 
        /* /M renvoie un tableau de pointeur sur des chaines */
        WHILE result[i]<>NIL
            WriteF('argument n°:\d =   ',5+i,result[i])
            i++
        ENDWHILE
        FreeArgs(rdargs)
    ELSE 
        WriteF('Usage: Number/N/A Number/N 
                                    Number/N Number/N text ...')
    ENDIF
ENDPROC


[Retour en haut] / [Retour aux articles] [Article précédent] / [Article suivant]