![]() |
Case Frage
Nur mal ne grundlegende Frage zu Delphi
Warum haben es die Delphiprogrammierer in eienr case struktur ausgeschlossen das case aus nem string zu bilden? ich meine: das ist doch/ wäre dochmanchmal sehr praktisch. mfg Nicodius |
Re: Case Frage
Sie haben es nicht ausgeschlossen. Es ist nicht möglich, da case nur mit ordinal Werten arbeitet.
|
Re: Case Frage
Ich glaub er meint, warum case nur mit ordinaltypen arbeitet! Warum also Borland das so gebaut hat´?
|
Re: Case Frage
öhm so verständnishalber mal ne kleine Beschreibung, was "ordinal" bedeutet, dann is das eigentlich klar ;)
Zitat:
Stephan |
Re: Case Frage
genau
sorry wegen falscher formulierung :stupid: was ordinal heißt das weiß ich aber geerell würde eine casestruktur genauso gut mit strings funktionieren da ZEICHEN K E T T E N also mehrere chars das hätten die leicht einbauen können :stupid: |
Re: Case Frage
Liste der Anhänge anzeigen (Anzahl: 1)
case kann grundsätzlich nur konstante Ordinalwerte benutzen. Und der Grund wird klar, wenn man sich den erzeugten Code ansieht:
Delphi-Quellcode:
Das erzeugt den im Anhang gezeigten Code. Da sieht man sehr schön, wie raffiniert der Compiler vorgeht: Er schreibt zunächst unser i in das Register EAX. Dann zieht er 2 davon ab. Nun prüft er, ob EAX gleich 0 ist, was der Fall gewesen wäre, wenn i=2 wäre. Nun zieht er noch eins und prüft wieder auf 0 (entspricht case 3). Ist bis hierher immer noch kein Sprung erfolgt, kommt ein unbedingter Sprung zur Anzeige von 'nix davon'.
var
i: Integer; begin i := 1; case i of 2: ShowMessage('2'); 3: ShowMessage('3'); else ShowMessage('nix davon'); end; end; Mit nicht konstanten Werten (geschweige denn mit Strings) wäre solch optimiertes Verhalten nicht möglich. Und soweit ich weiß, machen das andere Sprachen wie C(++) oder Java auch nicht anders. |
Re: Case Frage
warum zieht er was ab?
|
Re: Case Frage
Lies, was Chewie schreibt:
Zitat:
|
Re: Case Frage
Er prüft zunächst, ob i=2 ist. Dann prüft er, ob i=3 ist.
Wir schreiben nun unser i in EAX. Davon ziehen wir 2 ab. War i=2, steht jetzt eine 0 in EAX. War i<>2, könnte es 3 gewesen sein. Deshalb ziehen wir nochmal eins ab. War i=3, steht jetzt eine 0 drin. Sonst behandeln wir unseren else-Fall. Jetzt verstanden? |
Re: Case Frage
aha .. aber was ist daran so rafiniert :stupid:
wie soll er es denn sonst machen? .. naja um wieder OT zu werden: er kann so ja auch prüfen ob eine charKETTE vorhanden ist :? |
Re: Case Frage
Zitat:
|
Re: Case Frage
Das raffinierte dabei ist, dass das zero-flag gesetzt wird, sobald der Register bei einer Operation Null wird. Das passiert automatisch und kostet keinen Befehl Microcode. Darüber hinaus gibt es kaum einen Befehl mit kürzerem Microcode, als JZ (Springe, wenn Zero-Flag gesetzt ist).
Man nutzt hier sozuzagen die Tatsache aus, dass verschiedene Befehle innerhalb der CPU unterschiedlich schnell verarbeitet werden. Bei einem Vergleich von zwei Konstanten müsste die zweite erst in ein zweites Register geladen werden, und dann ein JE (Springe, wenn Register gleich) ausgeführt werden. Der JE macht im Microcode auch nix anderes, als die zweite von der ersten abzuziehen und ist genauso umfangreich wie die beiden Befehle im ersten Fall (DEC und JZ). Hierzu kommt dann noch bei jedem Case das Laden der Vergleichskonstante. |
Re: Case Frage
Ich wüsste auch gern mal warum das nicht geht, immerhin hat es ja früher in turbo pascal funktioniert!
mfg |
Re: Case Frage
Ganz sicher nur für Char, und das ist ein Ordinal.
|
Re: Case Frage
Zitat:
/EDIT: Sidorion's Aussage übersehen. Er sagt ja schon das gleiche aus. allgemein: Wenn du eine Case Schleife mit mehreren Werten machst, dann baut sich der Compiler dazu eine Sprungtabelle. d.h. er bringt den Wert auf die Basis 0 und multipliziert ihn mit 4 (bzw. shl 2) um dann den entstandenen Wert als Offset in einer Tabelle mit Sprungadressen nutzen um die richtige Adresse zu ermitteln und dann dort hin zu springen. Dies ist eleganter und schneller als ständig mit Bedingungsabfragen bestimmte Anweisungen zu überspringen und sich so einer Bedingungsliste durch zu hangeln. Dies ist Geschwindigkeits- und Grössenoptimierter Code. Wie sollte er sowas mit Strings bauen, wenn du niemals einen Ordinalen Typen hast den du zu einer solchen Adressierung benötigst. Bei Strings müsste er jeden einzelnen String an sich vergleichen um dann zu entscheiden ob er springt oder nicht. Dies fällt bei einer Sprungtabelle weg, da der Offset die Sprungadresse bestimmt und gleichzeitig der zu untersuchende Wert ist. Damit wird eine Abfrage des Wertes an sich unnötig. Nachteile der Sprungtabelle: Wenn du "Lücken" in deinen Zweigen hast bzw. diese nicht aufsteigend sind, dann können Sprungtabellen nicht angewendet werden bzw. haben dadurch mehr Code bzw. Overhead, so dass es sich nicht mehr lohnt (Vorteil ist zu gering gegenüber dem alten Weg). Anderer Punkt: Die Grenzen des Ordinaltyps müssen vorher abgefragt werden, da er sonst schliesslich in's Nirvana springen würden, wenn die Sprungtabelle verlassen würde bei der Adressierung. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:42 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz