Petite astuce avec les pointeurs

Informations pour bien débuter en PureBasic
Avatar de l’utilisateur
microdevweb
Messages : 1798
Inscription : mer. 29/juin/2011 14:11
Localisation : Belgique

Petite astuce avec les pointeurs

Message par microdevweb »

Imaginons que vous avez les variables suivantes,

Code : Tout sélectionner

Global MaVariable_1.l=0,MaVariable_2.l=0,MaVariable_3.l=0,MaVariable_4.l=0
Et que vous vouliez dans une boucle modifier les dites variables , hum comment faire ?

Voici une exemple avec l'utilisation de pointeurs

Code : Tout sélectionner

Global MaVariable_1.l=0,MaVariable_2.l=0,MaVariable_3.l=0,MaVariable_4.l=0
Procedure teste(*pt)
  Protected i
  For i=0 To 3
    PokeL(*pt+i*4,100 * i) ;4 représente la taille en octet d'un long
  Next
EndProcedure
teste(@MaVariable_1)
OpenConsole("Teste")
Print("Valeur de ma variable 1: ")
PrintN(Str(MaVariable_1))
Print("Valeur de ma variable 2: ")
PrintN(Str(MaVariable_2))
Print("Valeur de ma variable 3: ")
PrintN(Str(MaVariable_3))
Print("Valeur de ma variable 4: ")
PrintN(Str(MaVariable_4))
Input()
CloseConsole()
:!: :!: :!: Pour que ce système fonctionne il faut impérativement que
  • Les variables soit de même type
  • Les variables soit déclarée l'une à la suite des autres
Même chose mais en assembleurs, juste pour le fun

Code : Tout sélectionner

Global MaVariable_1.l=0,MaVariable_2.l=0,MaVariable_3.l=0,MaVariable_4.l=0
Procedure teste(*pt)
  EnableASM 
  MOV ebx,0
  !bcl_deb:
  MOV eax,dword[p.p_pt]
  CMP ebx,4
  JE bcl_fin
  MOV ecx,100
  IMUL ecx,ebx
  MOV dword[eax + ebx *4],ecx
  INC ebx
  JMP bcl_deb
  !bcl_fin:
  DisableASM
EndProcedure
teste(@MaVariable_1)
OpenConsole("Teste")
Print("Valeur de ma variable 1: ")
PrintN(Str(MaVariable_1))
Print("Valeur de ma variable 2: ")
PrintN(Str(MaVariable_2))
Print("Valeur de ma variable 3: ")
PrintN(Str(MaVariable_3))
Print("Valeur de ma variable 4: ")
PrintN(Str(MaVariable_4))
Input()
CloseConsole()
Windows 10 64 bits PB: 5.70 ; 5.72 LST
Work at Centre Spatial de Liège
Avatar de l’utilisateur
Micoute
Messages : 2522
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: Petite astuce avec les pointeurs

Message par Micoute »

Super, merci pour la partage

avec VectorDrawing, ça fait une console plus grande

Code : Tout sélectionner

Global MaVariable_1.l=0,MaVariable_2.l=0,MaVariable_3.l=0,MaVariable_4.l=0
Procedure test(*pt)
 Protected i
 For i=0 To 3
  PokeL(*pt+i*4,100 * i) ;4 représente la taille en octet d'un long
 Next
EndProcedure

InitSprite()
  InitKeyboard()
  InitMouse()
  
  Enumeration
    #Fenetre_principale
    #Canvas_principal
    #Texte
    #Sortie
    #Aucune
  EndEnumeration
  
  Global Police = FontID(LoadFont(#PB_Any, "Arial Rounded MT", 15, #PB_Font_Bold))
  
  Procedure VectorDrawText(X, Y, Texte$, CouleurTexte, Transparence = 255)
    VectorSourceColor(RGBA(Red(CouleurTexte), Green(CouleurTexte), Blue(CouleurTexte), Transparence))
    MovePathCursor(X, Y)
    DrawVectorText(Texte$)
  EndProcedure
  
  Procedure VectorBox(X, Y, Largeur, Hauteur, Couleur, Transparence = 255)
    VectorSourceColor(RGBA(Red(Couleur), Green(Couleur), Blue(Couleur), Transparence))
    AddPathBox(X, Y, Largeur, Hauteur)
    FillPath()
  EndProcedure
  
  Procedure Vector_LineXY(x1.d, y1.d, x2.d, y2.d, Epaisseur.d = 1.0, Couleur = 0, Transparence = 255)
 MovePathCursor(x1, y1)
 AddPathLine(x2, y2, #PB_Path_Default)
 ;VectorSourceColor(Couleur)
 VectorSourceColor(RGBA(Red(Couleur), Green(Couleur), Blue(Couleur), Transparence))
 StrokePath(Epaisseur)
EndProcedure
  
  If InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse() = 0
    MessageRequester("ERREUR","L'initialisation à échoué",#PB_MessageRequester_Error)
  EndIf
  
  ExamineDesktops() : Global  Largeur_Ecran = DesktopWidth(0) , Hauteur_Ecran = DesktopHeight(0) , Profondeur = DesktopDepth(0)
  Global x,y,z,Texte.s, h_Fenetre
  Largeur_Ecran-10 : Hauteur_Ecran-40 
  
  h_Fenetre = OpenWindow(#Fenetre_principale, 0, 0, Largeur_Ecran, Hauteur_Ecran, "Test", #PB_Window_ScreenCentered)
  OpenWindowedScreen(h_Fenetre, 0, 0, Largeur_Ecran, Hauteur_Ecran, 0, 0, 0, #PB_Screen_SmartSynchronization)
  
  CanvasGadget(#Canvas_principal, 0, 0, Largeur_Ecran, Hauteur_Ecran)
  
  ShowCursor_(#True) ; montrer le curseur
  StartVectorDrawing(CanvasVectorOutput(#Canvas_principal))
  VectorBox(0, 0, Largeur_Ecran, Hauteur_Ecran, #Black) ;pour nettoyer l'écran
  
  VectorFont(Police)
test(@MaVariable_1)

Texte = "Valeur de ma variable 1: "
VectorDrawText(x, y, Texte + Str(MaVariable_1), #Yellow)
y + VectorTextHeight(" ")
Texte = "Valeur de ma variable 2: "
VectorDrawText(x, y, Texte + Str(MaVariable_2), #Yellow)
y + VectorTextHeight(" ")
Texte = "Valeur de ma variable 3: "
VectorDrawText(x, y, Texte + Str(MaVariable_3), #Yellow)
y + VectorTextHeight(" ")
Texte = "Valeur de ma variable 4: "
VectorDrawText(x, y, Texte + Str(MaVariable_4), #Yellow)
y + VectorTextHeight(" ")

    Texte = "Pressez une touche ou cliquez pour sortir"
  VectorDrawText(Largeur_Ecran/2-VectorTextWidth(Texte)/2,Hauteur_Ecran-VectorTextHeight(" "), Texte, #White)
  ;- fin d'affichage
  StopVectorDrawing()
  
  ;- boucle d'événements
  Global action.i = #Aucune
  Repeat
    Global Evenement = WindowEvent()
    Select Evenement
      Case #PB_Event_CloseWindow
        action = #Sortie
      Case 0
        ExamineKeyboard()
        If KeyboardPushed(#PB_Key_All)
          action = #Sortie
        EndIf
        ExamineMouse()
        If MouseButton(#PB_MouseButton_Left) <> 0 
          action = #Sortie
        EndIf
        If MouseButton(#PB_MouseButton_Middle) <> 0 
          action = #Sortie
        EndIf
        If MouseButton(#PB_MouseButton_Right) <> 0 
          action = #Sortie
        EndIf
    EndSelect
  Until action = #Sortie
  ;- fermeture de l'écran & de la fenêtre
  CloseScreen()
  CloseWindow(#Fenetre_principale)
Plus de code à taper, mais on peut prévoir un fichier à inclure.
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 5.73 PB 6.00 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Avatar de l’utilisateur
Kwai chang caine
Messages : 6962
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Re: Petite astuce avec les pointeurs

Message par Kwai chang caine »

C'est un peu le même principe que pour modifier un tableau en une fois, il me semble....
Quant à l'ASM, je sais pas si tu viens d'apprendre ou si tu connaissais déjà...mais c'est fort 8)
Merci pour le partage 8)
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic
Avatar de l’utilisateur
Ar-S
Messages : 9472
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Petite astuce avec les pointeurs

Message par Ar-S »

Toute petite remarque, pour des variables du même type, si tu en as beaucoup, autant utiliser la syntaxe :
Global.type var1,var2,var3 etc...

Dans ton exemple :

Code : Tout sélectionner

Global.l MaVariable_1=0,MaVariable_2=0,MaVariable_3=0,MaVariable_4=0
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Avatar de l’utilisateur
microdevweb
Messages : 1798
Inscription : mer. 29/juin/2011 14:11
Localisation : Belgique

Re: Petite astuce avec les pointeurs

Message par microdevweb »

Merci pour l'astuce Ar-s
Windows 10 64 bits PB: 5.70 ; 5.72 LST
Work at Centre Spatial de Liège
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Petite astuce avec les pointeurs

Message par djes »

C'est quand même le genre de bidouille livrée sans garantie de fonctionnement dans le futur... Perso, j'utiliserais plutôt les tableaux, ou des pointeurs sur une zone mémoire contigüe...
Avatar de l’utilisateur
JohnJohnsonSHERMAN
Messages : 648
Inscription : dim. 13/déc./2015 11:05
Localisation : Allez, cherche...
Contact :

Re: Petite astuce avec les pointeurs

Message par JohnJohnsonSHERMAN »

Tout dépend de la gestion de la mémoire faite par le systéme, il se peut que sur certains systémes, ces variables ne soient pas contigues, je veux dire qu'il n'y a pas de garantie de leur contiguité...
Traditionellement, les pointeurs sont plutot utilisées pour l'accés au "tas" (heap), tandis que les variables se trouvent dans la pile (stack). Comme le programme ne controle pas le placement des variables dans la pile, ni l'emplacement des allocations dans le tas, miser sur une contiguité de plusieurs allocations successives est assez hasardeux, imaginons par exemple qu'un thread aie lui aussi alloué dans le même temps, il est probable que les allocations suivantes ne soient plus contigues...
Perso j'aurais aussi utilisé un tableau, quitte à le "malloquer"comme en C :

Code : Tout sélectionner

*tab = AllocateMemory(Size*SizeOf(int))
"Le bug se situe entre la chaise et le clavier"
Votre expert national en bogage et segfaults.

CPU : AMD A8 Quad core - RAM 8Gb - HDD 2To
  • Windows 10 x64 - PB 5.61 x64
  • Linux Ubuntu 16.04 LTS x64 (dual boot) - PB pas encore réinstallé
Avatar de l’utilisateur
majikeyric
Messages : 602
Inscription : dim. 08/déc./2013 23:19
Contact :

Re: Petite astuce avec les pointeurs

Message par majikeyric »

mon dieu, quelle niaiseries....
Dernière modification par majikeyric le lun. 03/juil./2017 14:56, modifié 1 fois.
Ollivier
Messages : 4190
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: Petite astuce avec les pointeurs

Message par Ollivier »

DJes a écrit :C'est quand même le genre de bidouille livrée sans garantie de fonctionnement dans le futur... Perso, j'utiliserais plutôt
les tableaux, ou des pointeurs sur une zone mémoire contigüe...
J'aurai la même optique : bien que ça marche parfaitement et que c'est le genre de possibilité qui existe depuis une paille, ça peut changer inopinément.
Répondre