Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht Das deutsche QBasic- und FreeBASIC-Forum
Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen  RegistrierenRegistrieren
ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin
Zur Begleitseite des Forums / Chat / Impressum
Aktueller Forenpartner:

Array Daten an SUB's, Array Rückgabewerte von SUB's
Gehe zu Seite 1, 2  Weiter
 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC.
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
FBTRON



Anmeldungsdatum: 10.04.2010
Beiträge: 3

BeitragVerfasst am: 10.04.2010, 17:01    Titel: Array Daten an SUB's, Array Rückgabewerte von SUB's Antworten mit Zitat

Hallo Experten !

Wie übergibt man eine Matrix (Array) über die Parameterliste an eine SUB und wie liefert eine Sub Rechenergebnisse (Matrix, Array) zurück an das aufrufende Programm und zwar ohne Arrays global zu deklarieren, OHNE -lang QB, OHNE -lang FBlite, OHNE -lang deprecated beim Kompilieren ?

Ich kann nicht begreifen, dass per default ab Version v0.17 alle Variablen als BYVAL an SUB's übergeben werden, das degradiert die Parameterübergabe an SUB's zur Einbahnstraße.

Wenn jemand einen einfachen Tipp hätte, ohne übermäßige Deklarationen und Umwege, wäre mir sehr geholfen .
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
MOD
Fleißiger Referenzredakteur


Anmeldungsdatum: 10.09.2007
Beiträge: 1003

BeitragVerfasst am: 10.04.2010, 17:06    Titel: Antworten mit Zitat

Hi,

ich finde es macht schon Sinn, alle Parameter ByVal zu übergeben, wenn du aber ByRef übergeben willst, dann gib das einfach an: ByRef

edit:
Das Übergeben eines Arrays ist einfach:

Code:
Sub foo (bar() As Integer)
   For i As Integer = LBound(bar) To UBound(bar)
      Print bar(i)
   Next
End Sub

Dim As Integer bar(1 To 3)

bar(1) = 5
bar(2) = 7
bar(3) = 1

foo(bar())

Sleep
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
FBTRON



Anmeldungsdatum: 10.04.2010
Beiträge: 3

BeitragVerfasst am: 10.04.2010, 17:33    Titel: Antworten mit Zitat

Hi MOD,

Das Übergeben eines Arrays ist einfach: Ja, simme ich Dir zu.

Aber Dein Beispiel ist doch die "Einhabnstraße", von der ich gesprochen habe.


Sub foo (bar() As Integer)
For i As Integer = LBound(bar) To UBound(bar)
bar(i) =bar(i) * 5
Next
End Sub

Dim As Integer bar(1 To 3)

bar(1) = 5
bar(2) = 7
bar(3) = 1

foo(bar())

for i =1 to 3
print bar(i)
NextSleep

Ausgabe müßte sein
10
14
2

Noch einmal meine Frage:
Wie liefert eine SUB über die Parameterliste
Ergebnisse an das aufrufende Programm zurück,
OHNE -lang .... beim Kompilieren ?

Ich will nicht meine gesamte Sammlung SUB's mit Matrixoperationen umbauen müssen .
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
MOD
Fleißiger Referenzredakteur


Anmeldungsdatum: 10.09.2007
Beiträge: 1003

BeitragVerfasst am: 10.04.2010, 17:41    Titel: Antworten mit Zitat

Wie gesagt, ByRef verwenden. Also die Sub so gestalten:
Code:
SUB foo (ByRef bar() AS INTEGER)


Damit kann die Sub die Werte des Arrays verändern und die Änderungen sind auch nach dem Aufruf noch vorhanden.

edit: Vergiss ByRef anzugeben, Arrays werden immer ByRef angegeben, also funktioniert das so schon richtig. Deine Aussage über die Ausgabe ist trotzdem falsch.
Zitat:
Ausgabe müßte sein
10
14
2


Da du mit 5 multiplizierst, muss 25, 23 und 5 rauskommen.


Zuletzt bearbeitet von MOD am 10.04.2010, 17:51, insgesamt einmal bearbeitet
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4704
Wohnort: ~/

BeitragVerfasst am: 10.04.2010, 17:48    Titel: Antworten mit Zitat

In der aktuellen fb-Version ist eine Array-Übergabe immer BYREF, BYVAL ist gar nicht mehr erlaubt.

FBTRON, welche FB-Version verwendest du? Bei mir lautet die Ausgabe
Code:
25
35
5

und genau das sollte bei einer Multiplikation mit 5 auch herauskommen.
_________________
Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1.


Zuletzt bearbeitet von nemored am 10.04.2010, 17:49, insgesamt einmal bearbeitet
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
FBTRON



Anmeldungsdatum: 10.04.2010
Beiträge: 3

BeitragVerfasst am: 10.04.2010, 17:49    Titel: Antworten mit Zitat

HI MOD,


ist mit vollkommen klar.
Ab Versioin v0.17.b muß bei Übergabe mit BYREF mit -lang QB oder -lang FBlite ... kompiliert werden, das macht die Version v0.20.0b kompatibel zur Version v0.16.

Kann man -lang FBlite vermeiden ??? -lang QB vermeiden ????
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
MOD
Fleißiger Referenzredakteur


Anmeldungsdatum: 10.09.2007
Beiträge: 1003

BeitragVerfasst am: 10.04.2010, 17:54    Titel: Antworten mit Zitat

Da war einer schneller als mein edit...

Zurück zum Thema, du musst nicht anders compilieren nur weil du ByRef verwendest. Die Aussage ist, dass standardmäßig ByVal verwendet wird, wenn nichts anderes angegeben wird in -lang fb. Wenn du aber normal ByRef angibst, dann kannst du trotzdem in -lang fb compileren.

Nur brauchst du kein ByRef, da Arrays im gegensatz zu normalen Variablen immer ByRef sind, auch in -lang fb.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Sebastian
Administrator


Anmeldungsdatum: 10.09.2004
Beiträge: 5969
Wohnort: Deutschland

BeitragVerfasst am: 10.04.2010, 17:54    Titel: Re: Array Daten an SUB's, Array Rückgabewerte von SUB's Antworten mit Zitat

FBTRON, den Programmausschnitt, den du gepostet hast, habe ich mit FB 0.20.0 und 0.21.0 (SVN) compiliert, und erhalte wie erwartet folgendes Ergebnis ohne -lang Parameter, d.h. implizit in -lang fb:


_________________

Die gefährlichsten Familienclans | Opas Leistung muss sich wieder lohnen - für 6 bis 10 Generationen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4704
Wohnort: ~/

BeitragVerfasst am: 10.04.2010, 18:00    Titel: Antworten mit Zitat

MOD hat Folgendes geschrieben:
du musst nicht anders compilieren nur weil du ByRef verwendest.

FBTRON hat insofern recht, dass sich das hier
Code:
Sub foo (byref bar() As Integer)

nicht mehr compilieren lässt. Bei normalen Variablen funktioniert das problemlos.
Code:
Sub foo (byref bar As Integer)

_________________
Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
MOD
Fleißiger Referenzredakteur


Anmeldungsdatum: 10.09.2007
Beiträge: 1003

BeitragVerfasst am: 10.04.2010, 18:10    Titel: Antworten mit Zitat

Da hab ich mich etwas allgemein ausgedrückt, also nochmal:

Arrays werden immer ByRef übergeben, egal welche Version und welcher FB-Dialekt.
ByRef muss und darf dabei auch nicht angegeben werden und ByVal darf erst recht nicht angegeben werden.

Ich finde ja, Arrays sollten auch ByVal sein, aber gut durchgeknallt


Hab das auch gleich in der Referenz vermerkt: Arrays
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4704
Wohnort: ~/

BeitragVerfasst am: 10.04.2010, 18:17    Titel: Antworten mit Zitat

Ich denke, der Grund für BYREF bei Arrays wird der sein, dass bei großen Arrays eine riesige Menge an Daten herumgeschaufelt werden müsste. Ansonsten gibt es ein paar seltene Fälle, in denen mir BYVAL auch lieber wäre. lächeln
_________________
Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
MOD
Fleißiger Referenzredakteur


Anmeldungsdatum: 10.09.2007
Beiträge: 1003

BeitragVerfasst am: 10.04.2010, 18:18    Titel: Antworten mit Zitat

Ja stimmt, dass könnte der Grund sein. ByVal erstellt immer Kopien und bei 10000 Elementen im Array wäre das kein Spaß.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
28398



Anmeldungsdatum: 25.04.2008
Beiträge: 1917

BeitragVerfasst am: 10.04.2010, 19:20    Titel: Antworten mit Zitat

Naja 10.000 Integers sind gerade mal 40kB. Klar, wenn man da eine recht großen UDT hat... Aber eigentlich gibt es dafür heute keinen Grund mehr. Der eigentliche Grund dürfte nämlich sein, dass FB Arrays auf'm Stack speichert. Und der ist Größenmäßig doch sehr eingeschränkt.
DAS sollte man vll. doch mal ändern.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Jojo
alter Rang


Anmeldungsdatum: 12.02.2005
Beiträge: 9736
Wohnort: Neben der Festplatte

BeitragVerfasst am: 10.04.2010, 19:35    Titel: Antworten mit Zitat

Das ist eigentlich ziemich normal, dass Parameter aufm Stack übergeben werden. Zunge rausstrecken
_________________
» Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
28398



Anmeldungsdatum: 25.04.2008
Beiträge: 1917

BeitragVerfasst am: 10.04.2010, 20:57    Titel: Antworten mit Zitat

afaik werden Arrays konstanter Größe aber immer im Stack gespeichert.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4704
Wohnort: ~/

BeitragVerfasst am: 11.04.2010, 12:23    Titel: Antworten mit Zitat

Das führt jetzt zwar etwas von der ursprünglichen Frage weg, aber zu
MOD hat Folgendes geschrieben:
Ich finde ja, Arrays sollten auch ByVal sein, aber gut durchgeknallt

funktioniert immerhin das hier:
Code:
type testtyp
  as integer arr(5)
end type

sub testsub(byval udt as testtyp)
  udt.arr(0) = 7
end sub

dim testvar as testtyp
testsub(testvar)
print testvar.arr(0)

_________________
Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
MOD
Fleißiger Referenzredakteur


Anmeldungsdatum: 10.09.2007
Beiträge: 1003

BeitragVerfasst am: 11.04.2010, 13:52    Titel: Antworten mit Zitat

Ja, das funktioniert, hat aber einen entscheidenden Nachteil - keine dynamischen Arrays. Man könnte das nun so machen:

Code:
Type testtyp
   As Integer size
   As Integer Ptr arr
End Type

Sub testsub(ByRef udt As testtyp)
   udt.size = 1
   udt.arr = Callocate(udt.size, SizeOf(Integer))
   udt.arr[0] = 7
   udt.arr[1] = 9
End Sub

Dim testvar As testtyp
testsub(testvar)
Print testvar.arr[0]
Print testvar.arr[1]
DeAllocate(testvar.arr)
Sleep


So gehen zwar "dynamische Arrays", aber ByVal führt zum Absturz des Programms und das ganze schaut doof aus und ist auch umständlich in der Verwendung.


Eine weitere Möglichkeit wäre das hier:

http://www.freebasic-portal.de/code-beispiele/kleine-helferlein/dynamische-arrays-in-types-168.html

Sicher nicht perfekt, aber ein Anfang und ByVal funktioniert wunderbar.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
croco97



Anmeldungsdatum: 04.11.2005
Beiträge: 260

BeitragVerfasst am: 11.04.2010, 21:04    Titel: Antworten mit Zitat

Um auch noch meinen Senf zum Thema zu geben:

Übergaben byvalue machen für nicht-einfache Typen (Arrays, Strings, UDTs) keinen Sinn, bzw. sind nicht sinnvoll möglich. Das ist in jeder Nicht-OOP-Programmiersprache so. Der Grund ist, dass eine richtige Kopie nur dann möglich ist, wenn ein deep copy-Konstruktor definiert ist. Und das ist sehr oft nicht der Fall.

Vielleicht habt Ihr's schon bemerkt, vielleicht auch nicht: Auch bei ganz normalen Strings gilt als Default auch in Ver. 0.20b weiterhin byref!

Um mir lange Ausführungen zu sparen: Standard ist, in solchen Fällen Zeiger zu übergeben. (Und die natürlich by value...). Weiterhin ist es guter Stil, Argumente nicht schreibend anzufassen, es sei denn, es ist der explizite Sinn der Methode (z.B. eine replace-Methode oder sowas). Dann hat man eigentlich wenig Probleme an der Front.

VG!

Croco
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4704
Wohnort: ~/

BeitragVerfasst am: 11.04.2010, 21:33    Titel: Antworten mit Zitat

Ich frag einfach mal so: angenommen, ich möchte einer FUNCTION ein Array übergeben, die soll die darin enthaltenen Daten auch auswerten, aber auf gar keinen Fall ändern können (vielleicht schreibe ich den Inhalt der FUNCTION ja auch nicht selbst, sondern jemand anderer). Ich denke mal, mit meinem UDT-Trick müsste das klappen, aber gibt es dafür eine bessere/sinnvollere Möglichkeit? Ich glaube, die PRIVATE-Methoden in fb lassen sich recht leicht aushebeln.
_________________
Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
MOD
Fleißiger Referenzredakteur


Anmeldungsdatum: 10.09.2007
Beiträge: 1003

BeitragVerfasst am: 11.04.2010, 21:43    Titel: Antworten mit Zitat

Mit Pointern kann man Private umgehen, wenn man die Struktur des UDTs kennt: http://www.freebasic-portal.de/porticula/private-mit-pointern-umgehen-1043.html

Statt das Array in ein UDT zu packen, kannst du auch wie im Code meines vorherigen Posts das Array als Integer Ptr tarnen. Ich hab das jetzt in einen Type gepackt, kann man aber auch ohne machen und den Pointer kann man dann ByVal übergeben.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC. Alle Zeiten sind GMT + 1 Stunde
Gehe zu Seite 1, 2  Weiter
Seite 1 von 2

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.

 Impressum :: Datenschutz