Seite 1 von 1
Diskussion über Unicdoe, Speicher und Pointer und so
Verfasst: 12.01.2007 20:39
von AND51
Hallo!
Dieser Thread stellt die Abspaltung des Threads
http://www.purebasic.fr/german/viewtopic.php?t=11598 dar, hier soll es (wie der Titel schon sagt), um Unicode im weitesten Sinne gehen.
@ remi_meier: Du schreibst:
> Auch ein String hat jetzt natürlich die doppelte Länge. Die Formel zum
Berechnen des Speicherverbrauches sieht so aus:
> Bytes = Len(String) * SizeOf(CHARACTER)
Gibt es nichts einfacheres? Zum Beispiel
MemorySize(@String) ?? Dann müsste man nicht immer mit 2 multiplizieren. Es sei denn, es gibt einen Befehl, der direkt den Speicherverbrauch eines Strings zurückgibt.
Ist übrigens
Len() oder
MemoryStringLength() schneller?
Ich habe mir endlich mal die vordefinierten Strukturen .l, .s, .b, .c usw. angesehen. Soll das heißen, dass ich sogar als Anfänger schon mit Strukturen gearbeitet habe, wenn ich schrieb "Define myString.s"?? Ich entdeckte, dass "myString" dann den Pointer zur Variablen enthält, und "myString\s" dann den eigentlichen String. ist das richtig?
Noch eine Frage:
remi_meier hat geschrieben:*p.CHARACTER = @String.s
*p\c ; aktuelles Zeichen
Wenn ich *p verändere, dann enthält doch *p\c automatsich das dazugehörende Zeichen, oder?
Verfasst: 12.01.2007 20:55
von Kaeru Gaman
> Ist übrigens Len() oder MemoryStringLength() schneller?
kein plan.. teste es doch...
>> Bytes = Len(String) * SizeOf(CHARACTER)
> Gibt es nichts einfacheres?
wie wärs mit
Bytes = MemoryStringLength(@string, #PB_Ascii)
...damit wird so getan, als sei der string im speicher ASCII,
also wird die länge in bytes zurückgegeben, auch wenn der string in unicode ist.
PS: ups.. geht gahnich...
in unicode könnte ne zwischen-null drinsein, die würde die function dann als terminator ansehen.. möp...
> Wenn ich *p verändere, dann enthält doch *p\c automatsich das dazugehörende Zeichen, oder?
sozusagen.
das zeichen steht auch weiterhin nur im string, du zeigst nur auf eine andere stelle des strings,
und die struct ermöglicht dir, ganz easy auf das zeichen zuzugreifen.
Verfasst: 12.01.2007 21:00
von AND51
Danke, verstanden.
> Bytes = MemoryStringLength(@string, #PB_Ascii)
Nee, sowas meine ich nicht; ich will automatisch, also abhängig davon, ob das Programm in ASCII oder Unicode programmiert wurde, die Bytes erfahren. Beispiel: "Kaeru". Bytes soll 5 sein, wenn Programm in ASCII, soll 10 sein, wenn in Unicode.
Verfasst: 12.01.2007 21:03
von remi_meier
Ok, werde noch ein wenig ergänzen.
Zu Speicherverbrauch:
StringByteLength() geht auch!
(dann hab ich noch den 0-Char vergessen ^^)
MemoryStringLength() bietet mehr Funktionen als Len(), aber obs schneller
ist, weiss ich nicht.
l, s, b, c sind keine Strukturen. LONG, STRING, BYTE, CHARACTER sind
Strukturen, die genau diese Typen beinhalten. Drücke mal Alt+S und
such nach diesen Strukturen.
Verfasst: 12.01.2007 21:22
von Kaeru Gaman
AND51 hat geschrieben:Danke, verstanden.
> Bytes = MemoryStringLength(@string, #PB_Ascii)
Nee, sowas meine ich nicht; ich will automatisch, also abhängig davon, ob das Programm in ASCII oder Unicode programmiert wurde, die Bytes erfahren. Beispiel: "Kaeru". Bytes soll 5 sein, wenn Programm in ASCII, soll 10 sein, wenn in Unicode.
genau das meinte ich ja...
es
würde ja auch funktionieren, wenn es nicht durch zwischennullen gestört würde...
beispiel:
ein wort mit fünf buchstaben steht im speicher,
das programm läuft in unicode -> 10 byte.
jetzt rufst du MemoryStringLength(@string, #PB_Ascii) auf,
er wird dir 10 sagen, weil er denkt, es sei ASCII.
aber es GEHT NICHT ZUVERLÄSSIG,
weil ein unicode-string auch nullen enthalten kann, die nicht die terminatoren sind!
Re: Diskussion über Unicdoe, Speicher und Pointer und so
Verfasst: 12.01.2007 21:25
von Leonhard
AND51 hat geschrieben:@ remi_meier: Du schreibst:
> Auch ein String hat jetzt natürlich die doppelte Länge. Die Formel zum
Berechnen des Speicherverbrauches sieht so aus:
> Bytes = Len(String) * SizeOf(CHARACTER)
Gibt es nichts einfacheres? Zum Beispiel MemorySize(@String) ?? Dann müsste man nicht immer mit 2 multiplizieren. Es sei denn, es gibt einen Befehl, der direkt den Speicherverbrauch eines Strings zurückgibt.
Verwende doch ein Macro:
Code: Alles auswählen
Macro LenEx(String)
Len(String)*SizeOf(Character)
EndMacro
Debug LenEx("String")
AND51 hat geschrieben:
Ich habe mir endlich mal die vordefinierten Strukturen .l, .s, .b, .c usw. angesehen. Soll das heißen, dass ich sogar als Anfänger schon mit Strukturen gearbeitet habe, wenn ich schrieb "Define myString.s"?? Ich entdeckte, dass "myString" dann den Pointer zur Variablen enthält, und "myString\s" dann den eigentlichen String. ist das richtig?
Es gibt vorgefärtigte Variablentypen, die du da schön auf gezählt hast (.l, .s, ...). Diese sind keine Strukturen (können so nicht aufgerufen werden). Sie werden direkt abgespeichert. Den aufbau einer Struktur kann man mit diesem Beispiel wohl am leichtesten kapieren:
Code: Alles auswählen
Structure MyStructure
long.l
byte.b[2]
;/ Ist das gleiche wie:
;byte1.b
;byte2.b
fixed_string.s{10}
string.s
double.d
EndStructure
Define *Pointer.MyStructure = AllocateMemory(SizeOf(MyStructure))
;/ Struktur wie gewohnt beschreiben:
With *Pointer
\long = 32462
\byte[0] = 1
\byte[1] = 2
\fixed_string = "0123456789"
\string = "String"
\double = 1.234
EndWith
;/ Daten aus der Struktur lesen:
Debug PeekL(*Pointer) ; \long
Debug PeekB(*Pointer+4) ; \byte[0]
Debug PeekB(*Pointer+4+1) ; \byte[1]
Debug PeekS(*Pointer+4+1+1, 10) ; \fixed_string
Debug PeekS(PeekL(*Pointer+4+1+1+10)) ; \string
Debug PeekD(*Pointer+4+1+1+10+4) ; \double
FreeMemory(*Pointer)
End
Wie man sehen kann, ist der normale String in der Struktur in einen .String -Pointer gefasst. Dies kommt daher, da der String vom System gegeben wird und nicht selbst definiert werden kann. Daher belegt der String in einer Struktur genauso viel wie ein Pointer und ein Pointer ist das gleiche wie eine Variable mit der Type Long, nur man kann den Pointer anders aufrufen.
AND51 hat geschrieben:Noch eine Frage:
remi_meier hat geschrieben:*p.CHARACTER = @String.s
*p\c ; aktuelles Zeichen
Wenn ich *p verändere, dann enthält doch *p\c automatsich das dazugehörende Zeichen, oder?
Der Code sagt es dir:
Code: Alles auswählen
String$="Hallo, PureBasic!"
Define *p.Character = @String$
Define i.l
For i = 1 To Len(String$)*SizeOf(Character)
Debug Chr(*p\c)
*p + SizeOf(Character)
Next i
End
AND51 hat geschrieben:
Ist übrigens Len() oder MemoryStringLength() schneller?
Len() ist Schneller. Nach folgendem Code weißt du mehr.
Code: Alles auswählen
Define String$="abcdefgbijklmnopqrstuvwxyz"
#Durchlaeufe= 1000000
Define lTime.l = ElapsedMilliseconds()
Define i.l
lTime.l = ElapsedMilliseconds()
For i = 1 To #Durchlaeufe
Len(String$)
Next i
Debug "Len: "+Str(ElapsedMilliseconds()-lTime)
lTime.l = ElapsedMilliseconds()
For i = 1 To #Durchlaeufe
MemoryStringLength(@String$)
Next i
Debug "MemoryStringLength: "+Str(ElapsedMilliseconds()-lTime)
End
Verfasst: 12.01.2007 21:31
von AND51
> l, s, b, c sind keine Strukturen. LONG, STRING, BYTE, CHARACTER sind
Strukturen, die genau diese Typen beinhalten.
'tschuldigung, genau das wollte ich aber eigentlich sagen.
> StringByteLength() geht auch!
Yehaaa, danke!!