- 12V Akku mit 280 Ah bauen         
Ergebnis 1 bis 8 von 8

Thema: Arrays an Sub oder Function übergeben

  1. #1
    Erfahrener Benutzer Roboter Genie Avatar von darwin.nuernberg
    Registriert seit
    08.08.2004
    Ort
    A, A
    Alter
    59
    Beiträge
    1.305
    Blog-Einträge
    1

    Arrays an Sub oder Function übergeben

    Anzeige

    Powerstation Test
    Hallo Bascomler,

    ich versuche verzweifelt nach einem Weg,
    wie ich ein Zahlenarray an eine Sub oder Function übergeben kann.

    (In anderen Basic Dialekten geht es so oder ähnlich, nur Bascom ist da wieder etwas anders)

    Egal was ich mache, immer wieder andere Probleme.

    Ist das nicht möglich oder übersehe ich da was.

    Keine genaue Dokumataion in der Hilfe


    Ich verwende das Bascaom 1.11.8.1

    Code:
    ' Àrray Demo
    '
    '
    
       $regfile = "m32def.dat"
       Baud = 19200
    
       Dim B_ar_werte(5) As Byte
       Dim X As Byte
    
       Declare Sub Arrayanzeigen(b_array(5) As Byte)
    
    
    
       For X = 1 To 5                                            ' einfache Schleife
         B_ar_werte(x) = X                                      ' Dem Array Werte Zuweisen
       Next X
    
    
       Print "Von Mainroutine aus :"                            ' Zum Beweis dass es hier funktioniert
       For X = 1 To 5                                           ' einfache Schleife
          Print "Folgender Wert ist in B_ar_werte(";
          Print X;
          Print ") enthalten :";
          Print B_ar_werte(x)                                      ' Inhalt des Arrays anzeigen.
          Print
       Next X
    
       Call Arrayanzeigen(b_ar_werte(5))                        ' Sub aufrufen und Array übergeben
    
    
    
    
       Do                                                       ' nur damit der Simulator weiter läuft
          nop
       Loop
    
       End                                                      'end program
    
       ' --------------------------------------------------------------------------
    
       Sub Arrayanzeigen(b_array(5) As Byte)
       Local Y As Byte
    
       Print "Von Suboutine aus :"
    
       For Y = 1 To 5                                           ' einfache Schleife
          Print "Folgender Wert ist in B_ar_werte(";
          Print Y;
          Print ") enthalten :";
          Print B_array(y)                                      ' Inhalt des Arrays anzeigen.
                ' Beim Compilieren kommt (nur in der SUB) Numeric parameter expected ???
          Print
       Next Y
    
    
       End Sub
    
       ' --------------------------------------------------------------------------
    
       End
    Ich habe die Sub auch schon mit BYVAL (Sub Arrayanzeigen(Byval b_array(5) As Byte)) deklariert dann geht es auch nicht.
    Kann mir jemand helfen?
    Gruss
    Darwin (meine Projekte sind auf meiner Pinnwand zu finden)

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    22.05.2005
    Ort
    12°29´ O, 48°38´ N
    Beiträge
    2.731
    Hallo,

    wenn man das so schreibt:
    Call Arrayanzeigen(b_ar_werte(5))

    wird doch nur dieser eine Wert übergeben, Array wert Nr. 5

    kann man da nicht nur den Namen angeben
    Call Arrayanzeigen(b_ar_werte)
    hab ich aber nicht probiert, ob das Bascom kapiert.

    Evtl. geht es aber wenn man den ersten Wert des Arrays ByRef übergibt, und dann selber weiterzählt !?

  3. #3
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    16.06.2004
    Ort
    Bad Schussenried in Oberschwaben
    Alter
    34
    Beiträge
    1.461
    Hi!

    Du hast das Array oben mit Dim als Global definiert (!= private)
    Also kannst du auch in den Subs drauf zugreifen.

    Wenn du es weitergeben würdest, bräuchtest du den doppelten Speicher.
    (schau mal nach deinem Stack.... Frame usw...)

    VLG Tobi
    http://www.tobias-schlegel.de
    "An AVR can solve (almost) every problem" - ts

  4. #4
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.842
    @Darwin: Du kannst das auch so machen
    Code:
    dim tabelle[juchuu]  as byte
    dim addresse as word
    
    declare sub anzeigen(addr as word)
    
    Aufruf:  
           addresse = varptr (tabelle(xx)) 
           call anzeigen(addresse)
    ............
    
    sub anzeigen(addr as word)
    Local Y As Byte 
    Local D As Byte 
    
       Print "Von Suboutine aus :" 
       For Y = 1 To 5                                           ' einfache Schleife 
          Print "Folgender Wert ist in B_ar_werte("; 
          Print Y; 
          Print ") enthalten :"; 
          D = INP(addr)
          Print D                                      ' Inhalt des Arrays anzeigen. 
          Print 
         incr addr
       Next Y 
    End Sub
    Die Ecke mit VARPTR ist notwendig, weil sich Bascom aus formalen Gründen weigert.

    Es ist nicht notwendig, byref hinzuschreiben, das nimmt er eh' an.
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  5. #5
    Erfahrener Benutzer Roboter Genie Avatar von darwin.nuernberg
    Registriert seit
    08.08.2004
    Ort
    A, A
    Alter
    59
    Beiträge
    1.305
    Blog-Einträge
    1
    Dankeschöööön:

    Ich hab ein bischen tüfteln müssen,
    die eckigen Klammern waren falsch,
    aber soweit geht es jetzt:

    Code:
       Dim Tabelle(5) As Byte
       Dim Addresse As Word
       Dim X As Byte
    
       Declare Sub Array_anzeigen(addr As Word)
    
    
       Aufruf:
           Addresse = Varptr(tabelle(1))
    
    
    
       For X = 1 To 5
          Tabelle(x) = X * 11
          Print "Schreibe Werte in Tabelle(";
          Print X;
          Print ") = ";
          Print Tabelle(x)
       Next X
           Call Array_anzeigen(addresse)
       Do
          nop
       Loop
    
       End                                                      'end program
    
    '  ............
    
       Sub Array_anzeigen(addr As Word)
       Local Y As Byte
       Local D As Byte
    
       Print "Von Suboutine aus :"
       For Y = 1 To 5                                           ' einfache Schleife
          Print "Folgender Wert ist in B_ar_werte(";
          Print Y;
          Print ") enthalten :";
          D = INP(addr)
          Print D                                      ' Inhalt des Arrays anzeigen.
         Incr Addr
       Next Y
       End Sub
    Soweit so gut.

    Ist möchte jetzt aber noch mehr.
    (kaum gibt man ihm den kleinen Finger...)


    Ist es möglich herauszufinden wie groß das Array dimensioniert wurde (ein- und/oder mehrdimensional) also z.B. (5) oder (2 , 5)?

    Dann könnte man ohne große Probleme verschiedene Tabellen mit der gleichen Routine bearbeiten ohne Gefahr in ein "out of range" zu laufen.

    Code:
    Print "Dimension = " ; Tabelle(0)
    geht auch nicht. (eindimensional)

    Dies wäre ein extra Bonbon.
    Gruss
    Darwin (meine Projekte sind auf meiner Pinnwand zu finden)

  6. #6
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.842
    *brabbel* Eckig tut mir leid, das is eine C-Krankheit

    So einen Wert wie "sizeof(aaa)" hab ich bei Bascom noch nicht finden können. aaaaber:
    da du ja nicht weißt, (in der sub) welches anfangselement du als param kriegst, würde die gesamtlänge gar nix nutzen. (ich) würde einfach eine Topadresse mitschicken
    Code:
    declare sub func (adr as word, top as word)
    
    dim tabelle(trallala)  as byte
    dim tabtop as word
           tabtop = varptr(tabtop) ' das ändert sich eigentlich nie
    
    dim tabaddr as word
           tabaddr = varptr(tabelle(xx))   ' je nach aufruf
           call func ( tabaddr, tabtop)   
     .....  
    sub func (adr as word, top as word)
    local xx as byte
       while adr < top
           xx = INP(adr)
           print xx
           incr adr
       wend
    Im Grunde funzt das auch bei mehrdimensionale Tabellen, da ja meist nur eine Dimension ungewiss ist. Aber man kann immer auch
    anfang = varptr(erstes Byte)
    endr = varptr(letzes Byte)
    übergeben.

    Anm: "Out of range" kannst du nur beim kompilieren kriegen, wenn du feste Zahlen verwendest. Zur Runtime liest er auch aus dem Nirwana, wenn's darauf ankommt und du einen Fehler hast.
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  7. #7
    Erfahrener Benutzer Roboter Genie Avatar von darwin.nuernberg
    Registriert seit
    08.08.2004
    Ort
    A, A
    Alter
    59
    Beiträge
    1.305
    Blog-Einträge
    1
    Zitat Zitat von PicNick
    *brabbel* Eckig tut mir leid, das is eine C-Krankheit
    Der Compiler hat da aber nicht gemeckert *zustimmbrabbel*




    Du meinst also jedem Aray so eine Art Header mit zu speichern?

    Ja das ginge schon, nur (vielleicht) wenn mal der Speicher knapp wird
    (Keine Ahnung wann es soweit ist) wäre eine Solche Funktion nicht schlecht um ein paar bytes zu sparen.


    PS: Ein Problem gibt es noch, habe ich aber gelöst.

    Du hattest in deinem Beispiel in der Sub den Adresspointer direkt incremmentiert. Irgendwie hat sich das weitergeschlichen und eine Folgende Sub mit gleichen aber localen Variablennamen hat das mitgekriegt (Ist dann evtl. byref der Standard?).

    Lieber solche Dinge explizit angeben, als dann lange suchen müssen.

    Ich habe jetzt eine zusätzliche Locale Variable (Pointer) der ich dann die Basisadresse zuweise und den Index aufaddiere.

    Dann braucht man byval auf jedenfall wenn man mit mehr als nur einem Parameter arbeitet. Sonst meckert der Compiler.

    Warum ist das so, mit nuer einem Parameter geht's doch auch?

    Für diejenigen welche es interresriert hier nochmal ein neuer Code.

    '
    Code:
     $regfile "m32def.dat"
    '
       Dim Tabelle(5) As Byte
       Dim W_addr As Word
       Dim X As Byte
    
       Declare Sub Array_anzeigen(wptr As Word )
       Declare Sub Array_aendern(byval Wptr As Word , Byval Modifikator As Byte )
    
    
    
    
      W_addr = Varptr(tabelle(1))
    
    
       Print "Hauptprogramm: Schreibe Werte in Tabelle an Adresse :";
       Print W_addr
    
       For X = 1 To 5
          Tabelle(x) = X * 11
          Print Tabelle(x) ;
          Print " ";
        Next X
        Print
    
       Print
       Print "Aufruf Unterprogramm mit Parameter :";
       W_addr = Varptr(tabelle(1))
       Print W_addr
       Call Array_anzeigen(w_addr)
       Call Array_aendern(w_addr , 100)
       Call Array_anzeigen(w_addr)
    
       Do
          Wait 1
    
       Loop
    
    End                                                         'end program
    
    ' ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
    
    Sub Array_anzeigen(wptr As Word )
       Local Bx As Byte
       Local Bd As Byte
       Local Pointer As Word
    
    
       Print
       Print "Unterprogramm Array_anzeigen"
       Print "----------------------------"
    
       Print "Übergebende Adresse = ";
       Print Wptr
       Print
    
    
       For Bx = 0 To 4                                          ' einfache Schleife
          Pointer = Wptr + Bx
    
          Print "Wert an Adresse ";
          Print Pointer;
          Print " enthält :";
          Print Inp(pointer )                                   ' Inhalt des Arrays anzeigen.
       Next Bx
       Return
       End Sub
    
    End                                                         'end program
    ' ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
    
       Sub Array_aendern(byval Wptr As Word , Byval Modifikator As Byte )
       Local Bx As Byte
       Local Bd As Byte
       Local Pointer As Word
    
    
       Print
       Print "Unterprogramm Array_anzeigen"
       Print "----------------------------"
    
       Print "Übergebende Adresse = ";
       Print Wptr
       Print
    
    
       For Bx = 0 To 4                                          ' einfache Schleife
          Pointer = Wptr + Bx
          Bd = Inp(pointer )                                    ' Inhalt des Arrays anzeigen.
          Bd = Bd + Modifikator
          Out Pointer , Bd
       Next Bx
       Return
       End Sub
    
    End                                                         'end program
    ' ----
    Gruss
    Darwin (meine Projekte sind auf meiner Pinnwand zu finden)

  8. #8
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.842
    Du sprichst da ein paar Sachen an, denen man nachgehen sollte.
    byval adr.: klaro, wenn du den gleichen Parameter mehrfach verwendest, brauchst du eine kopie je sub
    Ein parameter, den du mit einem Const belegst, MUSS natürlich byval sein.
    sonst sollte es da keine Einschränkung geben.
    Daten deskriptor: Bei Bascom ist eine besondere Flexibilität zu Runtime meist nicht notwendig, dimensions können sich ja nicht einfach ändern
    Du selbst könntest gut und gerne den Tabellen Index selbst als parameter handeln, da ja die Tabelle global ist. Das wär auch mehr Bascom-style.
    const tab_len = 242
    dim tabelle(tab_len) as byte

    call func (index )


    func (byval index as byte)
    while index <= tab_len
    ...
    wend
    Man muß halt immer entscheiden: elegante Sprach-Schweinerei oder nicht so elegant, aber sprachenrein.
    Was red' ich, das weißt du ja
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

12V Akku bauen