Author Topic: (Erledigt) Sowas wie ByRef als Funktionsrückgabe  (Read 5505 times)

Offline Markus

  • Mr. Polyvector
  • ***
  • Posts: 125
  • Offline
    • View Profile
Sowas brauche ich damit nicht jedes mal eine neue Struktur erzeugt wird.
Vieleicht geht sowas auch schon und ich weiß es noch nicht.

Code: GLBasic [Select]
FUNCTION >>>ByRef<<< FindPlayer AS TPlayer:Nr

                FOREACH P IN Players[]
                        IF P.Nr=Nr THEN RETURN P
                NEXT

ENDFUNCTION
 

Tatsache ist das ich hier den echten Inhalt vom Array bekomme
Code: GLBasic [Select]
                LOCAL P AS TPlayer
                FOREACH P IN Players[]
                        P.Draw()
                        IF P.Nr=1 THEN P.Update() //das geht
                NEXT
 

Plan B geht nicht  (das Byref ist bei PR wohl schon automatisch bei)
Code: GLBasic [Select]
FUNCTION FindPlayer:Nr, PR AS TPlayer

                FOREACH PR IN Players[]
                        IF PR.Nr=Nr                            
                                BREAK
                        ENDIF
                NEXT

ENDFUNCTION
 

Sowas macht eine Kopie
Code: GLBasic [Select]
FUNCTION FindPlayer:Nr, PR AS TPlayer

                FOREACH P IN Players[]
                        IF P.Nr=Nr  
                                PR=P
                                BREAK
                        ENDIF
                NEXT

ENDFUNCTION
 


« Last Edit: 2012-Apr-24 by Markus »

Offline backslider

  • Community Developer
  • Prof. Inline
  • ******
  • Posts: 892
    • View Profile
Re: Sowas wie ByRef als Funktionsrückgabe
« Reply #1 on: 2012-Apr-24 »
Geht nicht
Code: GLBasic [Select]
FUNCTION FindPlayer: Nr, BYREF p AS TPlayer
    FOREACH P IN Players[]
        IF P.Nr=Nr THEN p = P
    NEXT
ENDFUNCTION
 
?

Offline Quentin

  • Prof. Inline
  • *****
  • Posts: 915
    • View Profile
Re: Sowas wie ByRef als Funktionsrückgabe
« Reply #2 on: 2012-Apr-24 »
Meinst du sowas, dass die Funktion den Typen zurückliefert? Doch das geht schon. musst nur die Funktion entsprechend deklarieren:

Code: GLBasic [Select]
TYPE TPlayer
        text$
ENDTYPE

GLOBAL players[] AS TPlayer
DIM players[3]

players[0].text$ = "Erster"
players[1].text$ = "Zweiter"
players[2].text$ = "Dritter"

LOCAL test AS TPlayer

test = get_player("Zweiter")
STDOUT test.text$
KEYWAIT


FUNCTION get_player AS TPlayer: text$
        FOREACH p IN players[]
                IF p.text$ = text$
                        RETURN p
                ENDIF
        NEXT
ENDFUNCTION
 

Offline backslider

  • Community Developer
  • Prof. Inline
  • ******
  • Posts: 892
    • View Profile
Re: Sowas wie ByRef als Funktionsrückgabe
« Reply #3 on: 2012-Apr-24 »
Dein Beispiel hat er doch als erste Funktion genannt, nur das er da irgendwie nen BYREF haben will.  :P

Offline Kitty Hello

  • code monkey
  • Administrator
  • Prof. Inline
  • *******
  • Posts: 10723
  • here on my island the sea says 'hello'
    • View Profile
    • http://www.glbasic.com
Re: Sowas wie ByRef als Funktionsrückgabe
« Reply #4 on: 2012-Apr-24 »
Byref geht nicht. Aber Du kannst ja byref als argument übergeben.
Wenn Du BYREF returnen willst - worauf soll der Rückgabewert zeigen!?

Offline backslider

  • Community Developer
  • Prof. Inline
  • ******
  • Posts: 892
    • View Profile
Re: Sowas wie ByRef als Funktionsrückgabe
« Reply #5 on: 2012-Apr-24 »
Quote
Byref geht nicht. Aber Du kannst ja byref als argument übergeben.
Damit meinst Du doch meine Idee, oder nicht?

Offline Kitty Hello

  • code monkey
  • Administrator
  • Prof. Inline
  • *******
  • Posts: 10723
  • here on my island the sea says 'hello'
    • View Profile
    • http://www.glbasic.com
Re: Sowas wie ByRef als Funktionsrückgabe
« Reply #6 on: 2012-Apr-24 »
ja. genau.
...warum red ich überhaupt...

Offline kanonet

  • Administrator
  • Prof. Inline
  • *******
  • Posts: 1142
    • View Profile
    • My GLBasic code archiv
Re: Sowas wie ByRef als Funktionsrückgabe
« Reply #7 on: 2012-Apr-24 »
...warum red ich überhaupt...
:nana:
Lenovo Thinkpad T430u: Intel i5-3317U, 8GB DDR3, NVidia GeForce 620M, Micron RealSSD C400 @Win7 x64

Offline Markus

  • Mr. Polyvector
  • ***
  • Posts: 125
  • Offline
    • View Profile
Re: Sowas wie ByRef als Funktionsrückgabe
« Reply #8 on: 2012-Apr-24 »
byref bei einem Parameter mit Struktur gibt mir ein Syntax Error.
ich gehe aber davon aus das der Parameter eh schon als Pointer übergeben wird weil das nur ein paar Bytes sind und so üblich ist.
Oben mein Beispiel ging aber nicht wie ich das erwartet hatte.

Bei A=B habt ihr mir erklärt das dort die Struktur B nach A kopiert wird,ich will aber B haben original :-)

@Quentin
ich möchte keine kopie als Rückgabe

@Kitty Hello
ich will quasi Pointer tauschen bzw. weiter geben und Variable A durch B ersetzen vom gleichem Typ.
Das was im Array ist möchte ich mit einer Funktion raus suchen ohne eine kopie zu erstellen, dann mit .MachIrgendwas() ändern.
Ansonsten muß ich bei einer Kopie das ja auch wieder zurück kopieren in mein Array.
Und wenn man mit kopien arbeitet dann haben andere Funktionen wieder nicht das aktuelle.
Kopien kosten zu dem unnötig Zeit.

Was zum experimentieren:
Code: GLBasic [Select]

TYPE TPlayer
        Nr
        Name$
        x
        y
        Money

        FUNCTION Draw:
                SETPIXEL self.x,self.y,RGB(255,255,255)
        ENDFUNCTION

        FUNCTION Position: x,y
                self.x=x
                self.y=y
        ENDFUNCTION

        FUNCTION Update:

                //<- 203 Cursors
                //-> 205
                //^  200
                //V  208
                //o   28 RETURN

                LOCAL Name$=self.Name$ //for debug

                IF KEY(205)
                        IF self.x<800 THEN self.x=self.x+1
                ENDIF

        ENDFUNCTION

ENDTYPE

GLOBAL Players[] AS TPlayer

ALLOWESCAPE TRUE

MainLoop()
END

FUNCTION MainLoop:

        LOCAL A AS TPlayer
        A.Nr=1
        A.Name$="Markus"
        A.Position(100,300)

        LOCAL B AS TPlayer
        B.Nr=2
        B.Name$="Computer"
        B.Position(800-100,300)

        DIMPUSH Players[],A
        DIMPUSH Players[],B

        REPEAT

                LOCAL P AS TPlayer
                FOREACH P IN Players[]
                        P.Draw()
                        //IF P.Nr=1 THEN P.Update() //das geht
                NEXT
                FindPlayer(1,P)
                P.Update()              //das nicht weil das wohl eine Kopie der Struktur ist
                //ReplacePlayer(1,P) //Workaround

                SHOWSCREEN

        UNTIL FALSE

ENDFUNCTION

// P als BYREF gibt Syntax Error
FUNCTION FindPlayer: Nr, P AS TPlayer
    FOREACH P IN Players[]
        IF P.Nr=Nr
                BREAK
        ENDIF
    NEXT
ENDFUNCTION
 
« Last Edit: 2012-Apr-24 by Markus »

Offline Kitty Hello

  • code monkey
  • Administrator
  • Prof. Inline
  • *******
  • Posts: 10723
  • here on my island the sea says 'hello'
    • View Profile
    • http://www.glbasic.com
Re: Sowas wie ByRef als Funktionsrückgabe
« Reply #9 on: 2012-Apr-24 »
Keine Chance. Das Array ist ein echtes Array, keine Liste mit Pointern. Was in's Array soll, muss reinkopiert werden.
Bevor jetzt das Geheule über Geschwindigkeit losgeht, bitte erst ein konkretes Projekt machen und prüfen ob's wirklich "langsam" ist. Die GLB Arrays sind nämlich oft viel schneller als so linked-list Kram.

Offline Markus

  • Mr. Polyvector
  • ***
  • Posts: 125
  • Offline
    • View Profile
Re: Sowas wie ByRef als Funktionsrückgabe
« Reply #10 on: 2012-Apr-24 »
@Kitty Hello
Ich will doch direkt im Array arbeiten und hier mit dem Beispiel geht es ja auch.
Dieses P ist doch ein Block der im Speicher (Array) steht, den möchte ich auch bearbeiten.
Ich bekomme aber das P nicht aus einer Funktion zurück ohne das es als Kopie angelegt wird.
Wie ich das verstehe ist das P in dem Beispiel unten ein Pointer auf einen Speicherbereich wo die Struktur in echt ist oder ?
Wenn ich bei Update() mit self.xy=x einen Wert zuweise ist das wieder im Array darum gehe ich davon aus das P ein Ausschnitt vom Array ist.
LOCAL P AS TPlayer
FOREACH P IN Players[]
   P.Draw()
   IF P.Nr=1 THEN P.Update() //das geht
NEXT

Offline Schranz0r

  • Premium User :)
  • Administrator
  • Prof. Inline
  • *******
  • Posts: 5028
  • O Rly?
    • View Profile
Re: Sowas wie ByRef als Funktionsrückgabe
« Reply #11 on: 2012-Apr-24 »
INLINE  :enc:
I <3 DGArray's :D

PC:
AMD Ryzen 7 1700 @3.9GHz, 16GB HyperX Fury 3000MHz Ram, ASUS ROG GTX 1060 STRIX 6GB, Windows 10 Pro 64Bit, MSi Tomahawk B350 Mainboard

Offline Quentin

  • Prof. Inline
  • *****
  • Posts: 915
    • View Profile
Re: Sowas wie ByRef als Funktionsrückgabe
« Reply #12 on: 2012-Apr-24 »
@Quentin
ich möchte keine kopie als Rückgabe

ja sorry, hatte ich übersehen, hattest du ja schon probiert.

Was dein "P" hier angeht:
lt. Hilfe
"Man muss "ref" nicht als LOCAL definieren. Das passiert automatisch. Jedoch ist "ref" nach dem zugehörigem "NEXT" nicht mehr gültig."

Das beantwortet wohl, warum du nach der FOREACH-Schleife nicht mehr auf dein P zugreifen kannst. Und wenn du unbedingt direkt mit dem Array arbeiten willst, ohne irgendwelche Kopieraktionen, wieso arbeitest du dann nicht mit einem Index.

Anstatt FOREACH einfache FOR-Schleife:
Code: GLBasic [Select]
FOR i = 0 TO LEN(Players[]) - 1
    Players[i].draw()
NEXT

// damit kannst du dann auch außerhalb der Schleife gezielt über den Index zugreifen
// und deine gezeigte FindPlayer-Funktion wäre überflüssig

Players[5].update()
 


Offline Schranz0r

  • Premium User :)
  • Administrator
  • Prof. Inline
  • *******
  • Posts: 5028
  • O Rly?
    • View Profile
Re: Sowas wie ByRef als Funktionsrückgabe
« Reply #13 on: 2012-Apr-24 »
Und wenn du unbedingt direkt mit dem Array arbeiten willst, ohne irgendwelche Kopieraktionen, wieso arbeitest du dann nicht mit einem Index.

Richtig, mach es nach dem GLB-Way, oder nutze einfach INLINE...
Ist ja das coole an GLB das du mixen kannst :)
I <3 DGArray's :D

PC:
AMD Ryzen 7 1700 @3.9GHz, 16GB HyperX Fury 3000MHz Ram, ASUS ROG GTX 1060 STRIX 6GB, Windows 10 Pro 64Bit, MSi Tomahawk B350 Mainboard

Offline Markus

  • Mr. Polyvector
  • ***
  • Posts: 125
  • Offline
    • View Profile
Re: Sowas wie ByRef als Funktionsrückgabe
« Reply #14 on: 2012-Apr-24 »
@Quentin
ich wollte auch nicht nach der Schleife das P noch benutzen.
Das sieht jetzt nur in dem Beispiel so aus weil ich Experimente mache.
In der Funktion das P nach Außen geben .
Ich habe aber Explizite Deklaration an,warum nacht dann das ForEach
selber was ? Aber ich sehe grad dank dir wie das ForEach gemacht ist.
Da wird tatsächlich am Anfang und Ende alles kopiert, das muß ich ja dann
wohl auch so machen :-)

@Schranz0r
ihr habt mich grad auf die Idee gebracht das Array als Byref zu übergeben :-)

@Kitty Hello
hab dank Quentin ein Beispiel gefunden was das ForEach eigentlich macht.