Obligement - L'Amiga au maximum

Mercredi 17 octobre 2018 - 02:46  

Translate

En De Nl Nl
Es Pt It Nl


Rubriques

 · Accueil
 · A Propos
 · Articles
 · Galeries
 · Glossaire
 · 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 en d'autres langues


Twitter

Suivez-nous sur Twitter




Liens

 · Sites de téléchargements
 · Associations
 · Pages Personnelles
 · Matériel
 · Réparateurs
 · Revendeurs
 · Presse et médias
 · Programmation
 · Logiciels
 · Jeux
 · Scène démo
 · Divers


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


Contact

David Brunet

Courriel

 


Programmation : AMOS - Les pointeurs
(Article écrit par Jean Monos - mars 2018)


Voici un article sur les pointeurs en AMOS avec un morceau de C pour démystifier tout ça.

Les pointeurs en AMOS ? Non, la notion de pointeurs c'est en C et C++ ! L'AMOS c'est du BASIC, il n'y a pas de pointeur...

Je suis sûr que certains vont penser à ça quand ils vont lire cet article. Beaucoup de monde ne programme pas en C à cause des pointeurs qui souvent sont "difficiles" à mettre en place pour un débutant et surtout à comprendre. Je vais vous expliquer ce qu'est un pointeur, et vous proposer une utilisation en AMOS. Car oui, en AMOS et dans beaucoup de langages de type BASIC, les pointeurs existent !

Quèsaco un pointeur ?

Pour comprendre un pointeur, il faut comprendre un minimum la mémoire de votre ordinateur. Pour faire simple, la mémoire est découpée en cases. Chaque case représente un octet qui est une valeur entre 0 et 255. Chaque case possède un numéro (de 0 à je ne sais pas combien) en fonction de la mémoire disponible de votre ordinateur. Par exemple, pour la case numéro "1852", ce numéro de case s'appelle une adresse.

En C, on crée une variable dit "pointeur". Ce pointeur permet de mémoriser tout simplement une adresse mémoire de votre machine, et quand nous travaillons ce pointeur, nous modifions le contenu de la case mémoire dont l'adresse est contenue dans "cette variable".

En C, l'utilité première est donc de mémoriser, dans cette variable spéciale, l'adresse d'une autre variable que vous avez déclarée. Voici un petit code en C mais ne vous inquiétez pas, ce n'est pas compliqué à comprendre même si vous n'avez jamais fait de C.

int vie = 3 ;
int *pointeur_sur_vie = &age ;
printf("%d",*pointeur_sur_vie) ;

int vie =3 ;

Contrairement à l'AMOS, le C oblige à déclarer nos variables qui ici est "vie". En AMOS, nous le faisons pour les valeurs globales. Le petit mot "int" permet de définir la taille que va prendre la variable "vie". C'est ce que nous appelons le typage des variables. Normalement, et le plus souvent, un int c'est deux octets. En fonction des compilateurs, cela peut être une variable signée ou pas, c'est-à-dire que cela peut aller dans les positifs et les négatifs ou seulement les positifs (il existe des typages pour forcer afin d'être sûr que ce soit des variables signées (signed int) ou non signées (unsigned int). Il existe des typages sur 1, 4 ou 8 octets, cela permet de mieux gérer sa mémoire.

En AMOS, il n'existe que trois typages :
  • Les Integer (variable avec des nombres entiers).
  • Les Float/Real (variable avec des nombres à virgule).
  • Les String (variable à chaîne de caractères).
Chaque fois que vous utilisez une nouvelle variable, ce sont 4 octets pour les String et les Reals et cela dépend du contenu pour les Strings. Au niveau des tableaux, c'est pareil : chaque case représente 4 octets. Le C permet donc à ce niveau de bien travailler la mémoire.

Le "= 3" signifie simplement que nous affectons 3 à la variable "vie". Et en C, nous finissons une ligne d'instruction par un ";".

int *pointeur_sur_vie = &age ;

Nous allons créer la variable "pointeur_sur_vie" mais nous indiquons que ce sera une variable de type pointeur en ajoutant le "*" au début de la variable.

Le "&age" est tout simplement l'action de mémoriser l'adresse de la variable "age" dans la variable pointeur "*pointeur_sur_vie". Donc, le "&" devant une variable permet de localiser l'adresse de la variable en question.

printf("%d",*pointeur_sur_vie) ;

Cette fonction permet d'afficher à l'écran le contenu d'une variable dont l'adresse est contenue dans la variable "pointeur_sur_vie".

Quelle est l'utilité de tout ceci ? Quand on programme en C, c'est le compilateur qui dicte plus ou moins où va se trouver les variables dans la mémoire de la machine. En pratique, vous ne pouvez pas le savoir. Et dans beaucoup de cas (nous allons en voir un), nous avons besoin de modifier une valeur dans une case mémoire précise, et cette case mémoire est juste mémorisée par un pointeur.

Nous allons simuler le petit programme plus haut avec une petite variante après. Je simplifie les choses pour la compréhension générale.

int vie = 3 ;

Allez, le compilateur décide de réserver deux cases mémoire pour la variable "vie". Cases mémoire 100 et 101. Les deux cases mémoire représentent la valeur 3.

int *pointeur_sur_vie = &age ;

Zoom, le compilateur fait pareil avec pointeur_sur_vie mais il sait que cela va être un pointeur. Case mémoire 201 et 202. Ceci dit, dans la case mémoire 201 et 202, nous ne mémorisons pas le contenu de la variable "age" (qui est 3) mais son adresse. Donc la case 201 et 202 donneront tout simplement 100, qui est l'adresse de départ de la variable "age".

printf("%d",*pointeur_sur_vie) ;

Ce n'est pas le contenu de "*Pointeur_sur_vie" (qui est 100) qui sera affiché mais le contenu de la case 100 et 101 (donc 3). Ceci dit, si nous retirons l'étoile, ce sera le contenu de "pointeur_sur_vie" qui sera affiché, soit 100.

Une utilisation en C

Pour cela, nous allons faire un petit tour du côté des fonctions. Rappelons un petit point sur ceci : une fonction est un morceau de code qui renvoie un résultat. Une procédure, c'est un morceau de code qui ne renvoie pas de résultat. En AMOS, le terme "procédure" existe.

Procedure test
...
...
end proc

Tout comme en C, il peut prendre des arguments d'entrée et tout comme en C, cela peut se transformer en fonction en renvoyant une valeur et aller la rechercher avec la fonction "param" (c'est un peu plus lourd qu'en C, mais bon).

Ceci dit, le point commun entre les deux langages, c'est que cela ne peut renvoyer qu'un seul résultat ! Si vous avez plusieurs "variables" à modifier pour le reste du programme, soit vous vous débrouillez à créer plusieurs fonctions, soit vous passez en mode variable globale (en principe, on limite les variables globales), soit nous tapons directement dans les cases mémoire où se trouve les variables : d'où l'utilisation des pointeurs !

Voici un exemple de code en C pour modifier la vie et l'énergie. Le "main" est le point de départ du programme.

void test(int *pointeur_vie,int *pointeur_energie) ;

int main()
{
int vie =3 ;
int energie =100 ;
test(&vie,&energie) ;
printf("%d", vie);
printf("%d", energie);
return 0 ;
}

void test(int *pointeur_vie,int *pointeur_energie)
{
*pointeur_vie=5 ;
*pointeur_energie=50 ;

}

Voici un petit programme un peu bête mais qui va vous faire comprendre les pointeurs un peu mieux. Je passe "int vie" et "int energie" qui sont une déclaration de variable avec une affectation de valeur. 3 et 100.

test(&vie,&energie) ;

...est interagissant. Tout comme en AMOS, on appelle une procédure (ici "test") avec deux arguments et donc deux valeurs : l'adresse où se trouve la variable "vie" et l'adresse où se trouve la variable "energie". Ensuite, nous affichons à l'écran vie et energie.

void test(int *pointeur_vie,int *pointeur_energie)

Dans la procédure "test", nous déclarons deux variables de type pointeur. La première variable qui va mémoriser l'adresse de vie et la seconde variable qui va mémoriser l'adresse de la variable energie. Ensuite, nous modifions les cases mémoire pointées par les deux variables de type pointeur par 5 et 100.

*pointeur_vie=5 ;
*pointeur_energie=50 ;

Et à la sortie sur l'écran, nous affichons le contenu des deux variables pointées par nos deux pointeurs ! Pas besoin de deux fonctions, et pas besoin de déclarer des variables globales, c'est une programmation propre.

Et en AMOS ?

Vous lisez un article sur l'AMOS mais jusque-là, nous n'avons parlé que de C. Vous allez voir que l'AMOS sait aussi faire cela ! Ce n'est pas aussi intuitif mais l'AMOS sait le faire. D'abord, comment récupérer une adresse mémoire d'une variable en AMOS ? L'AMOS possède une fonction pour cela :

Varptr(variable)

Voici un exemple :

CHAT=5
Print Varptr(CHAT)
End

Dans mon test, l'écran n'affiche pas 5 mais 3388012 qui est une adresse mémoire.

Nous allons mémoriser dans une autre variable, l'adresse de la variable "CHAT".

Voici un second programme test :

CHAT=5
Print Varptr(CHAT)
ADR_CHAT=Varptr(CHAT)
Print ADR_CHAT
End

Ce programme mémorise donc l'adresse de "CHAT" dans la variable "ADR_CHAT". Quand je lance le programme, j'ai bien les deux mêmes nombres qui s'affichent (3388006 dans mon exemple).

Maintenant, nous allons voir comment lire le contenu d'une variable quand nous avons connaissance de son adresse. Pour cela, nous utilisons la fonction "Leek(ADRESSE)". "Leek" permet de lire une zone mémoire de 4 octets, et une variable en AMOS fait 4 octets ("Peek" c'est pour 1 octet et "Deek" c'est pour 2 octets).

Notez que quand je dis une zone mémoire de 4 octets, cela veut dire que les 4 octets en question sont réunis pour former une seule valeur à la sortie !

Voici un nouveau petit programme :

CHAT=5

ADR_CHAT=Varptr(CHAT)
Print Leek(ADR_CHAT)
End

Nous passons à "Leek" le contenu de "ADR_CHAT" qui est une adresse mémoire qui pointe sur "CHAT", et nous l'affichons à l'écran. Cela revient donc à faire, pour mon exemple :

CHAT=5
ADR_CHAT=Varptr(CHAT)
Print Leek(3388006)
End

Attention : les adresses mémoire changent, ce n'est ici qu'un exemple.

Maintenant, voyons voir comment nous pouvons changer la valeur d'une variable dont nous connaissons l'adresse. C'est simple, c'est l'utilisation de "Loke ADRESSE,VALEUR". "Loke" permet de modifier une zone mémoire sur 4 octets. "Doke" sur 2 octets et "Poke" sur 1 octet.

Nous continuons notre programme :

CHAT=5

ADR_CHAT=Varptr(CHAT)
Print Leek(ADR_CHAT)
LokeADR_CHAT ,50
Print Leek(ADR_CHAT)
Print CHAT
End

Le premier "print" sort bien 5 et le second sort bien 50. Et le "Print CHAT" balance bien 50 !

Et maintenant, passons à l'utilisation pratique des "pointeurs" dans une procédure.

Chat=5
Print CHAT
TEST[Varptr(CHAT)]
Print CHAT
End


Procedure TEST[ADR_CHAT]
Loke ADR_CHAT,50
End Proc

Alors, que fait ce petit programme ? Nous débutons avec la déclaration et l'affectation de 5 dans la variable "Chat" et nous l'affichons. Jusque-là, c'est normal. Ensuite, nous appelons la procédure "TEST" et nous lui passons l'adresse où se trouve la variable "CHAT", comme en C. Nous réaffichons ensuite "Chat" puis nous fermons le programme.

Dans la procédure, nous mémorisons l'adresse de "CHAT" dans la variable "ADR_CHAT". Avec "Loke", nous changeons les cases mémoire contenues dans "ADR_CHAT" par 50, ce qui correspond à la variable "Chat".

Quand nous lançons le programme, nous avons bien 5 qui s'affiche avant la procédure et 50 qui s'affiche après la procédure. Nous pouvons maintenant modifier plusieurs variables dans la procédure comme en C en passant en paramètre d'autres adresses de variable.

Voilà donc un petit article sur les pointeurs en AMOS avec un beau parallèle en C. Ce qui permet donc d'utiliser moins de variables globales et donc d'être plus lisible.


[Retour en haut] / [Retour aux articles]