Dynamisches Array

Ein Forum zum Erfahrungsaustausch und Hilfestellung in deutscher Sprache.

Dynamisches Array

Postby PMan » Sun Sep 05, 2010 1:56 pm

Hallo Miteinander,

ich habe einige Probleme mit der Definition von Arrays
Code: Select all
Dim sVal[] as String
    iAnzVal = 3
    ReDim sVal[1 To iAnzVal, 1 To 2]
    For iDS = 1 To iAnzVal
       sVal[iDS,1] = Trim(Left(sValStrs.String(iDS), InStr(sValStrs.String(iDS), "=")-1))
       sVal[iDS,2] = ....
    Next iDS

Beim Compilieren erhalte ich in der Zeile sVal[iDS,1] die Fehlermeldung:
"parser error: sVal different count of dimensions in line ... near Pos 19" (Pos 19 ist das Blank nach =)

Vereinbare ich Dim sVal[1,1] erhalte ich keine Fehlermeldung. Warum?

Vereinbare ich Dim sVal as New Array mault der Parser:
"parser error: incompatible types in assignemt: Left variable must be of type STRING or VARIANT in Line ..."
Welchen Type hat denn sVal bei dieser Vereinbarung?
PMan
 
Posts: 145
Joined: Sat Jul 03, 2010 12:31 pm
Location: Switzerland

Re: Dynamisches Array

Postby pappawinni » Sun Sep 05, 2010 7:38 pm

PMan wrote:...Vereinbare ich Dim sVal[1,1] erhalte ich keine Fehlermeldung. Warum? ...


ja, und wenn du
Dim sVal[]
vereinbarst (also ohne "as String") dann gibts auch kein Problem, oder ?
Weiss auch nicht, wie das zu erklären wäre.
Zumal, wenn es bis dorthin.
ReDim sVal[1 To iAnzVal, 1 To 2]
noch kein Problem zu geben scheint. Ich hab da mal
?lbound(sval,1), ubound(sval,1)
?lbound(sval,2), ubound(sval,2)
drangehängt und alles nachfolgende auskommentiert und das sieht zunächst mal gut aus.

Worüber ich kürzlich gestolpert bin war..
Code: Select all
dim arrA as variant = array(500,200,500)
dim i as integer

for i  = 0 to UBound(arrA)
  ? arrA(i)
next

arrA(0) = 1
for i  = 0 to UBound(arrA)
  ? arrA(i)
next

end sub

main()

Das Array hat zunächst die drei anfangs zugewiesenen Werte und ist sonst mit 0 gefüllt (Ubound = 10)
Wenn ich nun das erste Feldelement (Element 0) auf einen kleinen Wert setze, ändert sich offenbar der Typ der Variablen, jedenfalls
ändert sich nicht nur das erste Feldelement, sondern ich erhalte dann für das 3te Feldelement, das ursprünglich 500 war, nur noch 244
( 244+256 = 500)
Aber ok, das geht am Thema vorbei, denn das kannst du als dynamisches Array ohnehin nicht gebrauchen.

Es erscheint mir allerdings sinnvoll, ein 2-dimensionales Feld von vornhereein als 2-dimensional deklarieren.
Und wenn das funktioniert, so what.
Felder in der Anzahl der Dimensionen umzudeklarieren erschiene mir dann doch etwas fragwürdig.
Pappa makes everything what otherwise none likes :)
pappawinni
 
Posts: 192
Joined: Tue Jan 19, 2010 11:27 pm
Location: Germany

Re: Dynamisches Array

Postby berndnoetscher » Mon Sep 06, 2010 8:52 am

Beide Zeilen beziehen sich ja auf die gleiche Variable. Zuerst wird die Variable nur mit einer Dimension definiert. Redim kann nicht die Anzahl der Dimensionen ändern.

Dim sVal[] as String

ReDim sVal[1 To iAnzVal, 1 To 2]


Wenn du stattdessen

Code: Select all
Dim sVal[1, 1] as String


und dann redim verwendest, sollte es gehen.

(Frag mich nicht warum redim keine dimensionen ändern kann. Vielleicht hab ich es auch nur einfach übersehen.)

Variable [] und dann mit New Array() mischen geht nicht, weil Array ein Datentyp ist und [ ] auf fast all Datentypen angewendet werden kann.
berndnoetscher
Site Admin
 
Posts: 1059
Joined: Tue Sep 25, 2007 9:37 am

Re: Dynamisches Array

Postby PMan » Wed Sep 22, 2010 8:44 am

Hallo,

soweit habe ich das jetzt verstanden. Dann wollte ich ein dynamisch vereinbartes Array an eine Funktion bzw. Routine übergeben.
Code: Select all
Function1
Dim sVar[1,1] as String
Dim iAnz as Integer
  iAnz = ... 'berechnet die Anzahl der benötigten Zeilen
  ReDim s'Var[1 To iAnz, 1 To 7]
' Befehle zum Füllen von sVar
  ......
  Calk(cVar)
End Function1

Sub Calk(sVar())
  If sVar[1,1] <> "" Then
    ...
  EndIf

Fehlermeldung: parser error: sVar different count of dimensions in line ... near Pos 16

Wie muss ich den Aufruf der Routine formulieren, um dem Dimensionsproblem zu entgehen?
PMan
 
Posts: 145
Joined: Sat Jul 03, 2010 12:31 pm
Location: Switzerland

Re: Dynamisches Array

Postby pappawinni » Wed Sep 22, 2010 3:29 pm

o my god..
da werden mal eben die Dimensionen vertauscht und (P)man wundert sich dann auch,
warum das Ganze überhaupt irgendwas macht, wenn man ein feld ohne Typ dimensioniert,
aber wenn man "as string" dimensioniert, dann geht es brutal in die hose...

Unbrauchbar, schlicht und ergreifend unbrauchbar.

Code: Select all
sub main()
  Dim sVar[1,1]
  Dim iAnz as Integer
  Dim i as integer
  Dim j as integer
 
  '  iAnz = ... 'berechnet die Anzahl der benötigten Zeilen
  iAnz = 9
  ReDim sVar[1 To iAnz, 8 To 17]
  ' Befehle zum Füllen von sVar
  '  ......
  for i = 1 to iAnz
    for j = 8 to 17
      sVar[i,j]="(" & i & "," & J & ")"
    next
  next

  Calk(sVar)
End sub

Sub Calk( cVar[] )
  dim ub1 as integer
  dim ub2 as integer
  dim lb1 as integer
  dim lb2 as integer
  dim i as integer
  dim j as integer
  dim strOut as string

  lb1 = lbound (cVar,1): ub1 = ubound (cVar,1)
  lb2 = lbound (cVar,2): ub2 = ubound (cVar,2)

  ? "1st Dimension " & lb1 & " to " & ub1
  ? "2nd Dimension " & lb2 & " to " & ub2

  strOut = "" 
  for i = lb1 to ub1
    for j = lb2 to ub2
      strout = strout & cVar[i,j] & " "   
    next
    ? strOut
    strOut = ""
  next
end sub

main()


1
Pappa makes everything what otherwise none likes :)
pappawinni
 
Posts: 192
Joined: Tue Jan 19, 2010 11:27 pm
Location: Germany

Re: Dynamisches Array - Bug bei Übergabe

Postby PMan » Thu Sep 23, 2010 9:49 am

Hi Pappawinni,

was heißt da o my god..

Ich wollte ein Array mit String-Feldern haben und keins mit Varaint-Felder. Im KBasic Handbuch ist zu lesen: Arraydeklaration: Dim variableName[Index To Index, Index To Index, ...] As Type
und wenn diese Variable modulweit vereinbart ist, dann funktioniert dies auch. Nur übergeben lässt sich eine so definierte Variable anscheinend nicht. Es soll ja Basic-Derivate geben, in denen sich ein typisiertes Array auch übergeben lässt.

Nun gut es ist wie es ist. Ich habe den Code entsprechend geändert und es läuft - zumindest beim ersten Hinsehen. Beim Zweiten Hinsehen fällt auf, dass in der aufgerufenen Routine die Reihenfolge der Dimensionen vertauscht ist. Wurde in der aufrufenden Routine die Variable mit RiDim sVar[1 to 9, 8 To 17] definiert, liefert die aufgerufene Routine

iLB1 = LBound(sVar,1): iUB1 = UBound(sVar,1)
iLB2 = LBound(sVar,2): iUB2 = UBound(sVar,2)
Print "1st Dimension: " & iLB1 & " to " & iUB1 - 8 To 17
Print "2st Dimension: " & iLB2 & " to " & iUB2 - 1 To 9

Ist das bei Dir auch so?

Die Konsequenz von diesem Lapsus ist, dass das Array nicht mehr richtig ausgelesen werden kann. Der jetzt ausgegebene erste Datensatz umfasst die Felder 1 .. 7 des ursprünglichen ersten Datensatzes und die Feldert 1 .. 4 des zweiten Datensatzes. Der jetzt zweite Datensatz umfasst die Felder 5 .. 7 des ursprünglich zweiten Datensatzes und die Felder .... Man kann sehr gut sehen, dass das Array eine Aneinanderreihung von Speicherplätzen ist und die Indexe nur die Organisation des Array darstellen.
PMan
 
Posts: 145
Joined: Sat Jul 03, 2010 12:31 pm
Location: Switzerland

Re: Dynamisches Array

Postby pappawinni » Thu Sep 23, 2010 4:12 pm

Hi PMan,

oh my god... heisst... und das sagte ich schon.. die Dimensionen werden vertauscht, selbst wenn man ein variant array verwendet und das zunächst zu funktionieren scheint,
ist es anders als man denkt... und das ist dann schon ... wie soll ich sagen.. eine böse falle.

Wenn du mit arrays vom Typ String arbeiten willst, dann solltest du vielleicht mal schauen, ob es nicht besser ist, die Klasse Strings zu verwenden.
Also ich hatte auch in einer VBA-application ein Paramarray verwendet und beim protieren nach KBasic bin ich auf Strings umgestiegen.

http://www.kbasic.com/doku.php?id=objects#strings

0

Never wanted to post more then Henning or Slowdown..
Will have a break. CU
Pappa makes everything what otherwise none likes :)
pappawinni
 
Posts: 192
Joined: Tue Jan 19, 2010 11:27 pm
Location: Germany

Re: Dynamisches Array - Return - Werte

Postby PMan » Wed Sep 29, 2010 12:14 pm

Hallo Miteinander,

nachdem jetzt feststeht, dass das dynamische Array - zweidimensional - bei der Rückgabe aus einer Funktion einen Bug hat, es vertauscht die Dimensionen, muss ich leider feststellen, dass auch eindimensional nicht alles so funktioniert, wie es soll. Die Berechnung in der Funktion funktioniert reibungslos, nach der Rückgabe des Array an die aufrufende Routine hat das Array nur noch den ersten Wert, die anderen Werte sind 0, die Dimensionierung wird richtig ausgegeben - der bösen Falle 2. Teil

Bis wann wird die Baustelle Array geschlossen?
PMan
 
Posts: 145
Joined: Sat Jul 03, 2010 12:31 pm
Location: Switzerland

Re: Dynamisches Array

Postby pappawinni » Wed Sep 29, 2010 5:25 pm

Hi PMan,

hast du ein Beispiel ?
Also mit eindimensionalen Arrays funktioniert schon was, so isses ja nun nicht.

Code: Select all
sub main()
  Dim iVar[1] as integer
  Dim iAnz as Integer
  dim ub1 as integer
  dim lb1 as integer
  Dim i as integer
  Dim j as integer
 
  iAnz = 12
  ReDim iVar[iAnz]
  lb1 = lbound (iVar): ub1 = ubound (iVar)
  cls
  ? "main before Calc"
  for i = lb1 to ub1
    iVar[i] = i * 17  + 3
    ? iVar[i],
  next
  ?

  Calc(iVar)

  ? "main after Calc"
  lb1 = lbound (iVar): ub1 = ubound (iVar)
  for i = lb1 to ub1
    ? iVar[i],
  next
  ?
 
End sub

Sub Calc(ByRef inVar[] as integer )
  dim iiVar[1] as integer
  dim ub1 as integer
  dim lb1 as integer
  dim i as integer
  dim j as integer
  dim strOut as string
  ub1= ubound(inVar): lb1 = lbound(inVar)

   ? "CALC"
  for i = lb1 to ub1
   inVar[i] = inVar[i] \ 2
   ? inVar[i],
  next
  ?
 
end sub

main()
Pappa makes everything what otherwise none likes :)
pappawinni
 
Posts: 192
Joined: Tue Jan 19, 2010 11:27 pm
Location: Germany

Re: Dynamisches Array

Postby PMan » Thu Sep 30, 2010 10:06 am

Hi Pappawinni,

klar habe ich auch ein Beispiel. Übrigens im Beispiel Str2Byte habe ich in zwei Fällen Routinen verwendet, weil bei Funktionen die Rückgabe der Arrays nicht funktioniert hat.
Code: Select all
Dim aKey[32] As Byte
Private Sub cbSetKey_OnEvent()
    aKey = cv_BytesFromHex(tbKey.Value)
    For i = 0 To 32
      print akey[i]
    Next i
End Sub

Public Function cv_BytesFromHex(ByVal sInputHex As String) As Variant
' Returns array of bytes from hex string in big-endian order
' E.g. sHex="FEDC80" will return array {&HFE, &HDC, &H80}

Dim i As Integer
Dim M As Integer
Dim aBytes[] As Byte
Dim s as String
 
  If Len(sInputHex) Mod 2 <> 0 Then
    sInputHex = "0" & sInputHex
  End If

  M = Len(sInputHex) \ 2
  If M <= 0 Then
' Version 2: Returns empty array
    Return aBytes
  End If

  ReDim aBytes[M - 1]

  For i = 0 To M - 1
    s = Mid$(sInputHex, i * 2 + 1, 2)
    aBytes[i] = Val("&H" & Mid$(sInputHex, i * 2 + 1, 2))
    Print aBytes[i]
  Next i

  Return aBytes

End Function

tbKex.Value = fedcba9876543210
Der Code ist Teil eines Verschlüsselungsalgorithmus, der in VB geschrieben wurde. Der Ausdruck von akey ergibt für den ersten Wert 254 und für die restlichen 0, obwohl noch 7 weitere Werte <> 0 ausgegeben werden müssten. Natürlich könnte ich jetzt die Funktionen in Routinen umwandeln, aber es handelt sich um ca. 50 Funktionen, davon etliche mit Arrays als Rückgabewert, die sich gegenseitig aufrufen. Ich bin eigentlich schon froh, dass es sich in KBasic wieder übersetzen lässt.
PMan
 
Posts: 145
Joined: Sat Jul 03, 2010 12:31 pm
Location: Switzerland

Next

Return to Deutsches Forum (in German only)

cron