Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - AnsiChar und String


Skorsi - Mo 08.03.04 14:23
Titel: AnsiChar und String
Hallo,

wo ist eigentlich der Unterschied zwischen einem AnsiChar und einem String?
Bzw wie kann ich die beiden Typen konvertieren?

Danke, skorsi

Moderiert von user profile iconTino: Topic verschoben.


Motzi - Mo 08.03.04 15:06

Ein Char ist ein einzelnes Zeichen, während ein String eine Zeichenkette ist, also im Prinzip aus mehreren Chars besteht. Daher sollte damit auch die Frage nach der Konvertierung hinfällig sein...

BTW: auf die einzelnen Zeichen eines Strings kannst du direkt über ein Offset zugreifen, wobei bei de Strings gilt, das diese "1-indiziert" sind, das erste Zeichen also auch tatsächlich das Offset 1 hat. zB:

Delphi-Quelltext
1:
2:
3:
4:
procedure ShowFirstChar(const s: String);
begin
  ShowMessage('Das erste Zeichen ist ein: ' + s[1]);
end;


Delete - Mo 08.03.04 20:02

String ist ein von Delphi global verwendetes Wort, dass je nach Verwendung intern unterschiedliche effekte haben kann (AnsiString/ShortString).

AnsiString ist schon eher ein Typ in sofern als es immer ein dynamisches Array von Chars ist, also der Speicher erst belegt wird, wenn auch etwas hineingeschrieben wird. Das Ende des Strings wird duch ein 0-Byte angezeigt.
Alle Windows-Programme die untereinander Strings austauschen verwenden diesen Typ bzw. PChar also einen Pointer auf das erste Zeichen.

ShortString bzw. alle String[X] sind feste Arrays, deren Index 0 die Länge angibt.
- Sind schneller, verursachen weniger Speicherverschmutzung, sind aber eben maximal 255 Zeichen lang.
- Sollte man auch nur intern und untereinander verwenden.
- Sollte man auch nur an Prozeduren übergeben, die wirklich einen ShortString erwarten, also z.B nicht an die Prozedur oben, da der String sonst erst intern in einen AnsiString umgewandelt werden muss um übergeben werden zu können.

Zuweisungskompatibel sind sie aber alle zueinander.


Motzi - Mo 08.03.04 22:08

Brainiac hat folgendes geschrieben:
- Sind schneller, verursachen weniger Speicherverschmutzung

Naja, gilt nur eingeschränkt..! Bei ShortStrings wird bei einer simplen Zuweisung eines Strings an einen andren zB immer der ganze String kopiert während bei AnsiStrings nur Referenzen kopiert und Referenzzähler erhöht werden.. Und was die Speicherverschmutzung angeht.. man kann den Speichermanager ziemlich quälen aber wenn man richtig mit Strings arbeitet wird der Speicher bei weitem nicht so sehr fragmentiert wie man immer wieder erzählt. Außerdem belegen ShortStrings immer 256Bytes (bzw bei einem String[x] eben immer x+1 Bytes) während AnsiStrings immer nur so viel Speicher belegen wie nötig...


Delete - Mo 08.03.04 22:23

Wohl war, aber die meisten Operationen mit ShortStrings sind halt schneller.
Beim kopieren hast du aber recht, weswegen ich auch niemandem, der sich nicht wirklich auskennt empfehlen würde, mit ShortStrings zu arbeiten.


Motzi - Mo 08.03.04 22:30

Also das würd mich jetzt doch interessieren... welche Operationen sind beim ShortString schneller..? Klar gibt es ein paar, zB Zuweisung eines Strings, da bei AnsiStrings erst dyn. der Speicher reserviert wird.. aber sonst..? Welche Operationen meinst du mit meistens noch..?


Delete - Di 09.03.04 21:20

Also wenn bei einem String in kurzer Abfolge viele Teile hizugefügt oder entfernt werden sollen, dann sind statische Strings eigentlich immer schneller, weil halt der ganze Speicherreservierungsaufwand nicht getätigt werden muss.
Da das ja die üblichen Vorgänge mit Strings sind, hab ich das mal als meistens bezeichnet.

Dafür haben sie eben Nachteile beim Zuweisen, weswegen ich ja bei unveränderlichen Strings auch davon abgeraten habe.
Beim Suchen sind beide gleich schnell

Es sollte halt wirklich von der Anwendung abhängen, welchen Typ man nimmt.


Motzi - Di 09.03.04 21:58

Brainiac hat folgendes geschrieben:
Also wenn bei einem String in kurzer Abfolge viele Teile hizugefügt oder entfernt werden sollen, dann sind statische Strings eigentlich immer schneller, weil halt der ganze Speicherreservierungsaufwand nicht getätigt werden muss.

Und genau das sollte man ja eigentlich nicht machen..! Statt so einem Code:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
var
  s: String;
  i: Integer;

s := '';
for i := 1 to 100 do
  s := s + 'x';


sollte man sowas so machen:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
var
  s: String;
  i: Integer;

SetLength(s, 100)
for i := 1 to 100 do
  s[i] := 'x';


Delete - Di 09.03.04 23:31

Ok.
Auch wieder richtig für diese konkrete Situation.

ABER:
- Wenn du jetzt dem String etwas ganz neues zuweist, anstatt auf die einzelnen Chars zuzugreifen (was man wohl häuftiger macht), oder wenn du mit 'Delete' oder '+' arbeitest, dann wird der vorher belegte Speicher sofort wieder freigegeben, womit der Trick hier nicht greift.
Bei einem ShortString werden in so einem Falle einfach direkt mit Move die passenden Chars kopiert und das LängenByte verändert.

- Auch dein direktier Zugriff auf die Chars ist nicht so schnell wie der von ShortString weil für jeden Char einzeln die interne Prozedur 'UniqueStringA' aufgerufen werden muss, die noch ein paar Sachen überprüft.
Der Zugriff auf einen ShortString ist dagegen der gleiche wie auf ein Array, also direkt und damit schneller.


Motzi - Mi 10.03.04 13:49

Brainiac hat folgendes geschrieben:
- Auch dein direktier Zugriff auf die Chars ist nicht so schnell wie der von ShortString weil für jeden Char einzeln die interne Prozedur 'UniqueStringA' aufgerufen werden muss, die auf ausreichende Länge prüft.
Der Zugriff auf einen ShortString ist dagegen der gleiche wie auf ein Array, also direkt und damit schneller.

Stimmt, bei einem Schreibzugriff (aber nur beim schreiben!) wird intern immer UniqueString aufgerufen um zu prüfen ob mehrere Referenzen auf diesen String verweisen und falls das der Fall ist wird eine eigene Kopie des Strings angelegt. Ist das nicht der Fall kehrt UniqueString sofort wieder zurück. Der zusätzliche Aurfuf von UniqueString verbraucht also kaum Rechenzeit (höchstens wenn mehrere Referenzen auf den String verweisen), aber das ist eben der Preis den man für die interne Stringreferenzierung zahlen muss...


Delete - Mi 10.03.04 15:03

Nichts anderes haben ich je behauptet.


Motzi - Mi 10.03.04 22:42

Brainiac hat folgendes geschrieben:
Nichts anderes haben ich je behauptet.

Hab dir ja auch nicht widersprochen..! ;) Hab dich nur wiederholt und hinzugefügt, dass das eben der Preis für die interne Stringreferenzierung ist...! ;)