Ce post ne contient pas de question
Voici ce que j'aurais aimé trouver à mes débuts sur la gestion des chaines, et en espérant que ça puisse aider les suivants.
Commentaires, remarques et corrections d'erreur sont les bienvenus.
Les variables
Code : Tout sélectionner
#ChaineCourte = "AZBY" ;Définition d'une constante de type chaine
Chaine.s = #ChaineCourte ;Initialisation de la variable de type chaine par une constante. Notez le type .s
Chaine_2.s = "CXDW" ;Initialisation de la variable de type chaine avec une chaine de caractère
Debug Chaine ;Affichage de la chaine
Code : Tout sélectionner
Chaine.s = "AZBY"
Chaine_2.s = Chaine + Chaine_2
Debug Chaine_2 ;Affichage de la chaine
Chaine_2 = Chaine + "-----" + Chaine
Debug Chaine_2 ;Affichage de la chaine
Code : Tout sélectionner
Chaine.s = "AZBY"
Chaine_2.s = Chaine + Chr(32) + "A" + Chr(13) + "Deuxième ligne" ;Ajout des caractères ' '(espace), 'A', et retour à la ligne
;l'affichage de Debug ne traite pas les caractères 'spéciaux' => rendu par MessageRequester
MessageRequester("AVEC retour à la ligne", Chaine_2)
Chaine_2 = Chaine + Chr(32) + "A" + "Deuxième ligne" ;Ajout des caractères ' '(espace), 'A',
MessageRequester("SANS retour à la ligne", Chaine_2)
Code : Tout sélectionner
;ATTENTION : L'adresse d'une chaine est l'adresse de son premier caractère
;Mais pour accéder au caractère d'une chaine, il faut utiliser le bon type de pointeur
*PtrGood.BYTE ;Il faut passer par un type .BYTE (de format structure)
*PtrBad.b ;et non un type .b
Chaine.s = "AZBY"
*PtrGood = @Chaine
*PtrBad = @Chaine
;- Affichage de l'adresse de la chaine
Debug @Chaine ;Affichage de l'adresse de la chaine
Debug *PtrGood ;Affichage de la valeur du pointeur (normalement égal à la valeur de @Chaine)
Debug *PtrBad ;Affichage de la valeur du pointeur (normalement égal à la valeur de @Chaine)
Code : Tout sélectionner
Chaine.s = "AZBY"
*PtrGood.BYTE = @Chaine
Debug Chr(*PtrGood) ;Affiche le LSB de l'adresse de la chaine
Debug Chr(*PtrGood\b) ;Affiche A, premier caractère de la chaine
Code : Tout sélectionner
Chaine.s = "AZBY"
*PtrBad.b = @Chaine
Debug Chr(*PtrBad) ;Affiche le LSB de l'adresse de la chaine
;Debug Chr(*PtrBad\b) ;Génère une erreur de compilation car le type .b n'est pas une structure
Code : Tout sélectionner
Chaine.s = "AZBY"
*PtrGood.BYTE = @Chaine
Debug Chr(*PtrGood\b + 1) ;Affiche B, caractère suivant A dans la table ASCII (i.e. A(64) + 1 = B(65 dans la table ASCII)
;Debug Chr((*PtrGood + 1)\b) ;Génère une erreur de compilation : nombre de paramètre incorrect
Code : Tout sélectionner
Chaine.s = "AZBY"
*PtrGood.BYTE = @Chaine
*PtrGood+1 ;Correspond à *PtrGood = *PtrGood + 1
Debug Chr(*PtrGood\b) ;Affiche Z, caractère suivant A dans la chaine
;Autre méthode
*PtrGood = @Chaine + 3 ;On pointe l'adresse de départ plus un décalage (ici 3)
Debug Chr(*PtrGood\b) ;Affiche Y, sans besoin de parcourir toute la chaine
Code : Tout sélectionner
Chaine.s = "AZBY"
Dim PtrProcS.s(2) ;Le tableau contient des valeurs de type chaine
PtrProcS(0) = Chaine ;Affectation d'une valeur chaine au tableau
Debug PtrProcS(0) ;Affiche la chaine
Code : Tout sélectionner
Chaine.s = "AZBY"
Dim PtrProcL.l(2) ;Le tableau contient des adresses, donc des valeurs numériques
PtrProcL(0) = @Chaine ;Affectation d'une valeur d'adresse de chaine au tableau
Debug PtrProcL(0) ;Affiche l'adresse de la chaine
Debug PeekS(PtrProcL(0)) ;Récupère la chaine à partir de son adresse et affiche la chaine
Code : Tout sélectionner
Chaine.s = "AZBY"
Dim *PtrProcB.BYTE(2) ;Le tableau contient des adresses, donc des valeurs numériques
*PtrProcB(0) = @Chaine ;Affectation d'une valeur d'adresse de chaine au tableau
Debug *PtrProcB(0) ;Affiche l'adresse de la chaine
Debug Chr(*PtrProcB(0)\b) ;Affiche A, premier caractère de la chaine
Code : Tout sélectionner
;Une chaine est par nature terminée par un caractère NULL (valeur hexadecimal 0)
Chaine.s = "AZBY"
Dim *PtrProcB.BYTE(2) ;Le tableau contient des adresses, donc des valeurs numériques
*PtrProcB(0) = @Chaine ;Affectation d'une valeur d'adresse de chaine au tableau
While *PtrProcB(0)\b ;Tant que le caractère NULL n'est pas atteint
Debug Chr(*PtrProcB(0)\b) ;Affiche le caractère suivant de la chaine
*PtrProcB(0) + 1 ;Incrementation de la valeur du pointeur => on pointe le caractère suivant
Wend
Code : Tout sélectionner
;ATTENTION : Si un caractère NULL est inséré dans la chaine, celui-ci marquera la nouvelle fin de cette chaine
Chaine.s = "AZBY"
Dim *PtrProcB.BYTE(2) ;Le tableau contient des adresses, donc des valeurs numériques
*PtrProcB(0) = @Chaine + 2 ;On pointe le caractère B
*PtrProcB(0)\b = 0 ;On remplace B par le caractère NULL
*PtrProcB(0) = @Chaine ;On repositionne le pointeur au début de la chaine
*PtrGood = *PtrProcB(0) ;On copie la variable de type pointeur de caractère de chaine dans une variable de type pointeur de chaine
Debug PeekS(*PtrGood) ;La chaine n'est plus que "AZ"
Code : Tout sélectionner
#ChaineCourte = "AZBY" ;Définition d'une constante de type chaine
Procedure.s RetourneChaine() ;Le type de la fonction est .s
ProcedureReturn #ChaineCourte
EndProcedure
Debug RetourneChaine() ;Affichage de la chaine
Code : Tout sélectionner
;Attention :
; - Si une variable n'est pas déclarée globalement, elle sera déclarée automatiquement en tant que variable locale
Global Chaine.s
Chaine = "AZBY"
Procedure.s RetourneChaine_2();Le type de la fonction est .s
ProcedureReturn Chaine ;Si Chaine n'est pas déclarée en Global, Chaine est ici une variable numeric
EndProcedure ;ce qui génère une erreur de compilation : "expect string"
Debug RetourneChaine_2() ;Affichage de la chaine
Code : Tout sélectionner
;Attention :
; - Il ne faut pas retourner l'adresse d'une variable locale, car après le EndProcedure,
; les variables locales n'existent plus
; - Pour retourner une adresse, il faut déclarer une variable globale et locale portant le même nom
; et retourner l'adresse de la variable globale
Global Res.s ;Variable Global servant pour le passage de la valeur de retour
Chaine.s = "AZBY"
Procedure.l RetourneAdChaine();Le type de la fonction est un NUMERIC : .l
Res.s = Chaine ;Si Chaine n'est pas déclaré en Global, cette ecriture génère
ProcedureReturn @Res ;une erreur de compilation : numeric to string
EndProcedure
Debug "Passage par variable Global"
Debug PeekS(RetourneAdChaine());Récupère la chaine à partir de son adresse
;Autre solution passage par une variable en paramètre : ici, Chaine n'aurait pas besoin d'être déclarée en Global
Procedure.l RetourneAdChaine_2(ChaineTmp.s)
Res.s = ChaineTmp
ProcedureReturn @Res
EndProcedure
Chaine.s = "AZBY"
Debug "Passage par une variable en paramètre de fonction"
Debug PeekS(RetourneAdChaine_2(Chaine));Récupère la chaine à partir de son adresse
;Autre solution passage par un pointeur en paramètre : ici, Chaine n'aurait pas besoin d'être déclarée en Global
Global *Res.l
Procedure.l RetourneAdChaine_3(*ChaineTmp.l)
*Res.l = *ChaineTmp
ProcedureReturn *Res
EndProcedure
Chaine.s = "AZBY"
Debug "Passage par un pointeur en paramètre de fonction"
Debug PeekS(RetourneAdChaine_3(@Chaine));Récupère la chaine à partir de son adresse
Code : Tout sélectionner
;Procedure.BYTE Test() ;Erreur de compilation
;EndProcedure
Code : Tout sélectionner
;Resultat = CallFunctionFast(*PointeurFonction [,Parametre1 [, Parametre2...]])
;CallFunctionFast permet d'appeler une fonction en passant par l'adresse de cette fonction : *PointeurFonction
;Le nombre de paramètres autorisés est quelconque mais doit correspondre exactement aux besoins de la fonction
;Resultat contient le résultat de la fonction appelée.
;ATTENTION :
;CallFunctionFast ne retourne que UNE VALEUR NUMERIC, que l'on peut traiter en tant qu'adresse, ou valeur.
;CallFunctionFast ne retourne pas de chaine
;Ceci implique qu'il faut faire attention lorsque l'on code des fonctions que l'on souhaite être appelées par un CallFunctionFast.
;Ces fonctions ne doivent pas retourner de chaine, mais un pointeur de chaine.
Global Res.s ;Variable Global servant pour le passage de la valeur de retour
Chaine.s = "AZBY"
Procedure.l RetourneAdChaine_2(ChaineTmp.s)
Res.s = ChaineTmp
ProcedureReturn @Res
EndProcedure
*PtrProc.l = @RetourneAdChaine_2() ;Stockage de l'adresse de la fonction RetourneAdChaine_2
Resultat.l = CallFunctionFast(*PtrProc, Chaine)
Debug PeekS(Resultat)