Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - length(string) etwas zuweisen


Mathematiker - Fr 16.05.14 13:49
Titel: length(string) etwas zuweisen
Hallo,
um meinen "Lieblingen" wenigstens die Grundlagen der Programmierung einzutrichtern, habe ich folgende "Regel" aufgestellt:
"Links steht immer eine variable Größe!"
Grund ist, dass ich öfters a+b := 12; sin(a) := 0.5 usw. usf. geliefert bekomme.
Ein paar besonders "nette" Schüler suchen nun solange, bis sie eine Ausnahme finden; nach der Methode: Ich weiß etwas, was sie nicht wissen! Ätsch!

Konkret geht es um die Funktion length bei einem String. Folgendes ist möglich:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
procedure TForm1.Button1Click(Sender: TObject);
var  s : string[26];
     r : string;
begin
     s:='ABCDEFGHIJKLMNOPQRSTUVWXYZ';
     memo1.lines.add(s);
     length(s):=20;           //das wird compiliert
     memo1.lines.add(s);      //20 Zeichen werden angezeigt
//     s[0]:=13;               wird nicht compiliert
     length(s):=40;
//     s[27]:='#';             wird nicht compiliert
     memo1.lines.add(s);      //26 und nicht 40 Zeichen werden angezeigt,
                              //d.h. der String wurde bei length(s):=20 nicht wirklich gekürzt

     r:='ABCDEFGHIJKLMNOPQRSTUVWXYZ';
     memo1.lines.add(r);
//     length(r):=20;          wird nicht compiliert
     setlength(r,20);
     memo1.lines.add(r);      //20 Zeichen werden angezeigt
     setlength(r,30);
     memo1.lines.add(r);      //20 Zeichen werden angezeigt, die letzten 6 sind "weg"

end;

D.h., ist der String auf eine Zeichenanzahl begrenzt, kann ich seine wirksame Länge direkt verändern. Das ist insofern logisch, da dann im 0.Byte die Länge des String steht. Dies widerspricht auch nur scheinbar meiner "Regel".
Meine Fragen: Ist die direkte Änderung der Stringlänge auch in modernen Delphi-Versionen möglich? Bei Delphi 5 und 7 geht es jedenfalls.
Werden Strings des Typs string[anzahl] tatsächlich noch als klassische Pascal-Strings oder doch als nullterminierte verwaltet? Im 2.Fall dürfte die Zuweisung length(string):=xxxx ja eigentlich nicht gehen.

Danke und Beste Grüße
Mathematiker


ZeitGeist87 - Fr 16.05.14 14:08

Hallo,

hab´s grad mal mit XE2 probiert.

Alles wie bei dir in D5-D7


Gruß,
Stefan


WasWeißDennIch - Fr 16.05.14 14:49

Was mich ein wenig verwundert: System.Length ist eine Funktion und keine Property einer Klasse, wie will man der denn von außerhalb einen Wert zuweisen?


jaenicke - Fr 16.05.14 15:06

Das ist Compiler Magic...
Length ist keine echte Funktion, sondern wird vom Compiler direkt umgesetzt.

s ist hier ein ShortString. Bei dem steht die Länge im ersten Byte (an Stelle 0, daher sind Strings auch 1-basiert). ShortStrings sind auch die Ausnahme, da geht einiges, was bei "normalen" Strings nicht geht. Konkret lässt sich die Länge so setzen wie hier gezeigt, aber auch so:

Delphi-Quelltext
1:
s[0] := #13;                    
Passieren tut in beiden Fällen das gleiche:

Quelltext
1:
2:
Unit609.pas.32: length(s):=20;           //das wird compiliert
005B8E6B C645D914         mov byte ptr [ebp-$27],$14
Sprich es wird nur in dieses erste Zeichen, in dem die Länge steht, die neue Länge geschrieben. An dem String wird aber sonst nichts verändert.


WasWeißDennIch - Fr 16.05.14 15:10

Dann kann man aber doch auch z.B. schreiben

Delphi-Quelltext
1:
s[0] := Chr(27);                    

, solange man dabei unter 256 bleibt und es sich um einen ShortString (also mit Längenbyte) handelt.

[edit] Nee, wenn dann wohl besser
s[0] := AnsiChar(27);[/edit]


jaenicke - Fr 16.05.14 15:17

Das ist doch das gleiche. :nixweiss:


WasWeißDennIch - Fr 16.05.14 15:31

Erscheint mir persönlich aber verständlicher, als einer Funktion einen Wert zuzuweisen.


jaenicke - Fr 16.05.14 15:53

Ich meinte jetzt das gleiche wie das was ich geschrieben hatte:
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:

Delphi-Quelltext
1:
s[0] := #13;                    
Ich dachte du wolltest auf die Funktion Chr hinaus.

Dass die Syntax mit length einen Wert zuweisen seltsam aussieht, ist klar.

Aber ShortStrings sind ja sowieso am Aussterben... zum Glück. ;-)


Mathematiker - Fr 16.05.14 16:47

Hallo,
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Aber ShortStrings sind ja sowieso am Aussterben... zum Glück. ;-)

Ich schlussfolgere daraus, dass das Problem sich perspektivisch erledigt.
Es ist zwar (noch) möglich, die Länge eines Shortstrings direkt zu ändern, aber zum einen etwas sinnlos und zum anderen ein Rudiment früherer Sprachversionen.

Beste Grüße
Mathematiker


jaenicke - Fr 16.05.14 16:49

Man kann ShortStrings noch weiter nutzen, solange man nur für Windows entwickelt, auch mit XE6. Man sollte es nur möglichst nicht. Für die mobilen Plattformen (iOS und Android) sind diese nicht verfügbar, da gibt es nur UnicodeStrings.


SMO - Mi 21.05.14 18:09

Totgesagte leben länger. [http://andy.jgknet.de/blog/2013/10/the-return-of-the-byte-strings/] ;)

Ich behaupte nicht, dass es empfehlenswert ist, die alten Stringtypen unter iOS und Android zu benutzen. Aber wer unbedingt will, der kann.


jaenicke - Mi 21.05.14 20:40

user profile iconSMO hat folgendes geschrieben Zum zitierten Posting springen:
Ich behaupte nicht, dass es empfehlenswert ist, die alten Stringtypen unter iOS und Android zu benutzen. Aber wer unbedingt will, der kann.
Es ist in 99% der Fälle einfach nur dumm diese Hacks zu nutzen. Denn da die nicht offiziell verfügbar sind, sitzt man mit Quelltext, der die nutzt, dann ggf. dumm da, wenn eine neue Delphiversion kommt, in der die wirklich nicht mehr drin sind. Und bei mobilen Plattformen kommt man ja kaum um ein Upgrade herum...

Es gibt nur sehr wenige Fälle, in denen das wirklich Sinn macht die zu nutzen. In fast allen Fällen war es einfach nur "ich will aber"... :roll: