ABOUT Visual Basic Programmieren Programmierung Download Downloads Tips & Tricks Tipps & Tricks Know-How Praxis VB VBA Visual Basic for Applications VBS VBScript Scripting Windows ActiveX COM OLE API ComputerPC Microsoft Office Microsoft Office 97 Office 2000 Access Word Winword Excel Outlook Addins ASP Active Server Pages COMAddIns ActiveX-Controls OCX UserControl UserDocument Komponenten DLL EXE
Diese Seite wurde zuletzt aktualisiert am 07.09.2000

Diese Seite wurde zuletzt aktualisiert am 07.09.2000
Aktuell im ABOUT Visual Basic-MagazinGrundlagenwissen und TechnologienKnow How, Tipps und Tricks rund um Visual BasicActiveX-Komponenten, Controls, Klassen und mehr...AddIns für die Visual Basic-IDE und die VBA-IDEVBA-Programmierung in MS-Office und anderen AnwendungenScripting-Praxis für den Windows Scripting Host und das Scripting-ControlTools, Komponenten und Dienstleistungen des MarktesRessourcen für Programmierer (Bücher, Job-Börse)Dies&Das...

Themen und Stichwörter im ABOUT Visual Basic-Magazin
Code, Beispiele, Komponenten, Tools im Überblick, Shareware, Freeware
Ihre Service-Seite, Termine, Job-Börse
Melden Sie sich an, um in den vollen Genuss des ABOUT Visual Basic-Magazins zu kommen!
Informationen zum ABOUT Visual Basic-Magazin, Kontakt und Impressum

Zurück...

Arrays auf den Kopf stellen

Zurück...


Anzeige

(-hg) mailto:hg_reversearray@aboutvb.de

Fällt Ihnen irgendeine wirklich sinnvolle Verwendung der ab Visual Basic 6 vorhandenen Funktion StrReverse ein? Zu mehr als einem mehr oder eher weniger lustigen Gag scheint sie wohl nicht zu gebrauchen zu sein. Denn ein InStrRev gibt es ja auch seit VB 6, so dass das Umkehren eines Strings auch nicht notwendig ist, um ihn vom Ende her durchsuchen zu können.

Aber da ein String, auf Speicherebene betrachtet, schließlich nichts anderes als eine Kette von Byte-Werten ist, die ASCII-/ANSI-Zeichen repräsentieren... oder nichts anderes als eine Kette von Integer-Werten ist, die Unicode-Zeichen repräsentieren...?

Richtig! Sie können die Funktion StrReverse dazu missbrauchen, die Reihenfolge der Werte in einem Byte- oder in einem Integer-Array umzukehren.

Bei einem Byte-Array ist die Angelegenheit harmlos und einfach. Da die Visual Basic-Syntax es erlaubt, einen String einem Byte-Array zuzuweisen, und umgekehrt, brauchen Sie sich lediglich um die richtige Form der Zuweisung kümmern. Da VB intern einen String als Unicode-String verarbeitet, jedes Zeichen also von 2 Bytes repräsentiert wird, müssen Sie mit der Funktion StrConv und der Konstanten vbUnicode dafür sorgen, dass jedes einzelne Byte als ein Zeichen betrachtet wird. Nach der Umkehrung des Strings durch StrReverse hat die Zuweisung in umgekehrten Sinne zu erfolgen, wobei aus jedem Zeichen wieder ein Byte wird. Dafür sorgt wieder die Funktion StrConv, diesmal mit der Konstanten vbFromUnicode.

Public Function ReverseArrayByte(Bytes() As Byte) As Byte()
  Dim nStr As String
  
  nStr = StrConv(Bytes, vbUnicode)
  nStr = StrReverse(nStr)
  ReverseArrayByte = StrConv(nStr, vbFromUnicode)
End Function

Die Umkehrung eines Integer-Arrays ist ein wenig komplizierter. Sie müssen nämlich zunächst einmal dafür sorgen, dass das Integer-Array in ein Byte-Array überführt wird, dann die Umkehrung vornehmen, und anschließend das sich so ergebende Byte-Array wieder in ein Integer-Array überführen. Wenn Sie diese Überführungen in Schleifen erledigen wollten, könnten Sie auch gleich die umgekehrte Zuordnung vornehmen - der Witz und die Notwendigkeit der StrReverse-Funktion wären obsolet.

Aber wie Sie ja bereits wissen, sind auch die Integer-Arrays lediglich eine Folge von Speicherstellen, wobei jeweils zwei Speicherstellen, also zwei Bytes, eine Integer-Zahl repräsentieren. Und diese Speicherstellen können blockweise kopiert werden - ein Integer-Array-Block kann auf einen Byte-Array-Block kopiert werden. Sie müssen einzig darauf achten, dass der Byte-Array-Block genau so viele Bytes wie der Integer-Array-Block bereitstellt.

Gehen wir einmal davon aus, dass die Untergrenze eines umzukehrenden Integer-Arrays standardmäßig 0 sein soll, dann entspricht die Anzahl der Elemente der Obergrenze des Arrays plus 1. Die Anzahl der Elemente mit 2 multipliziert ergibt die Anzahl der benötigten Bytes. Die Obergrenze des Byte-Arrays muss nun wieder um ein (Byte!-)Element kleiner sein, als die Anzahl der Bytes. Die Anweisung zur Dimensionierung des Byte-Arrays lautet also:

ReDim ByteArray((UBound(IntegerArray) + 1) * 2 - 1)

Das Kopieren des Speicherblocks übernimmt die API-Funktion MSDN Library - API CopyMemoryCopyMemory (die eigentlich "RtlMoveMemory" heißt). Sie erwartet als Parameter die Start-Speicheradresse des Ziels, die Start-Speicheradresse der Quelle und die Anzahl der zu kopierenden Bytes. Die Speicheradressen erhalten Sie vom jeweils ersten Element der beiden Arrays über die undokumentierte VB-Funktion VarPtr. Beachten Sie, dass die Speicheradressen als Wert zu übergeben sind, also ausdrücklich mit der Angabe ByVal. Die Anzahl der zu kopierenden Bytes ergibt sich ganz einfach aus der Obergrenze des Byte-Arrays plus 1.

Da wir aber nicht auch die Reihenfolge der beiden Bytes eines jeweiligen Integer-Elements auch umkehren dürfen, erübrigt sich hier die zur Umkehrung eines Byte-Arrays benötigte Unicode-Konvertierung. Es reicht, das Byte-Array einfach einem String zuzuweisen, diesen mit StrReverse umzukehren, und ihn wieder dem Byte-Array zuzuweisen.

Nun wird das Byte-Array wieder in ein Integer-Array der gleichen Größe wie die des ursprünglichen Integer-Arrays zurückkopiert - und schon macht auch ein Integer-Array einen Kopfstand...

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
 (pDest As Any, pSrc As Any, ByVal ByteLen As Long)

Public Function ReverseArrayInt(Ints() As Integer) As Integer()
  Dim nBytes() As Byte
  Dim nStr As String
  Dim nInts() As Integer
  
  ReDim nBytes((UBound(Ints) + 1) * 2 - 1)
  CopyMemory ByVal VarPtr(nBytes(0)), ByVal VarPtr(Ints(0)), _
   UBound(nBytes) + 1
  nStr = nBytes
  nStr = StrReverse(nStr)
  nBytes = nStr
  ReDim nInts(UBound(Ints))
  CopyMemory ByVal VarPtr(nInts(0)), ByVal VarPtr(nBytes(0)), _
   UBound(nBytes) + 1
  ReverseArrayInt = nInts
End Function

Arrays anderer Datentypen lassen sich auf diese Weise allerdings nicht umkehren - bei mehr als zwei Bytes je Element kann dieser Trick ja nicht funktionieren.


Modul modReverseArray (modReverseArray.bas - ca. 1 KB)


Artikel
Zum Download-Bereich dieses Artikel
Mail an den Autor dieses Artikels

KnowHow
Zur KnowHow-Übersicht

KnowHow-Themen
Themen - Allgemeines
Themen - Entwicklungsumgebung (VB-IDE)
Themen - Forms
Themen - Steuerelemente (Controls)
Themen - Grafik
Themen - Dateien
Themen - UserControls
Themen - Einsteiger-Tipps
Themen - Wussten Sie...?

Übersicht nach Titeln in alphabetischer Reihenfolge
Übersicht nach Erscheinungsdatum

Schnellsuche



Zum Seitenanfang

Copyright © 1999 - 2017 Harald M. Genauck, ip-pro gmbh  /  Impressum

Zum Seitenanfang

Zurück...

Zurück...

Download Internet Explorer