Delphi-Quellcode:
zusammen mit
procedure Test (pi: PInteger);
Delphi-Quellcode:
Geht aber auch nicht! Denn IntToStr velangt einen Parameter. Und den kann eine Prozedur nicht liefern.
showmessage (IntToStr (Test (8));
Desshalb müsste die Routine Test schon eine Funktion sein.
Delphi-Quellcode:
function Test (pi: PInteger);
|
@ Hansa
zu deiner Frage: Wieso ist da kein Rückgabewert. Eine Funktion liefert einen Rückgabewert
Delphi-Quellcode:
Diese Funktion hat einen Rückgabewert vom Typ Integer mit dem Wert 5.
function Test : integer;
begin result := 5; end; Eine Prozedur hat keinen Rückgabewert
Delphi-Quellcode:
Diese Prozedur hat keinen Rückgabewert, sondern sie pinselt hier nur den Wert 5 in die Adresse der Variable die du ihr Übergibst.
procedure Test (VAR i : integer);
begin i := 5; end; Deshalb kannst du auch nicht das machen:
Delphi-Quellcode:
Das würde funktionieren:
begin
showmessage (IntToStr (Test (8)); end;
Delphi-Quellcode:
In der Messagebox würde eine 5 stehen.
var i : integer;
begin i := 2; Test (i); showmessage (IntToStr (i); end; Alles klar? mfg Daniel |
Zitat:
|
@Chewie
Weis ich doch, mein Post sollte als Ergänzung zu deinem gesehen werden :D Ich denkmal mittlerweile ist das auch geklärt, oder? |
Zitat:
|
Zitat:
|
Hä? Du hast die 5 nicht als Konstante deklariert :?:
|
Das Argument, daß C++ keine Unterscheidung kennt ist etwas naiv!
C wurde nämlich erfunden um Programmierern das Leben schwer zu machen. Laßt mich mal ein wenig tiefer buddeln: Delphi-Code. Es ist eine Prozedur und eine Funktion! ... STDCALL wurde verwendet um den Unterschied anschaulicher darzustellen, da Delphi ansonsten diverse Parametertypen (u.a. Integer) im Register übergibt.
Delphi-Quellcode:
Etwas Pseudo-Code:
procedure prozedur(var i:Integer); // Anschaulicher!!!
begin i:=i+1; end; function funktion(i:Integer):Integer; stdcall; // Anschaulicher!!! begin result:=i+1; end; procedure TForm1.Button1Click(Sender: TObject); var i:Integer; begin i:=funktion(5); // ergebnis 6 prozedur(i); // ergebnis 7 end;
Code:
Uns interessieren die Stellen zwischen den: "~~~~~~~~~~~~~~".
procedure prozedur(var i:Integer); stdcall;
-------------- push ebp // EBP sichern mov ebp, esp // Stack Frame ~~~~~~~~~~~~~~ mov eax, [ebp+$08] // "EAX := @i" inc dword ptr [eax] // EAX^ := EAX^ + 1 // inc(EAX^) ~~~~~~~~~~~~~~ pop ebp // EBP wiederherstellen ret $04 // Rückkehren -------------- function funktion(i:Integer):Integer; stdcall; -------------- push ebp // EBP sichern mov ebp, esp // Stack Frame ~~~~~~~~~~~~~~ mov eax, [ebp+$08] // EAX := i inc eax // i := i + 1 // inc(i) ~~~~~~~~~~~~~~ pop ebp // EBP wiederherstellen ret $04 // Rückkehren -------------- procedure TForm1.Button1Click(Sender: TObject); -------------- push $05 // Parameterübergabe call 0043C6AC // Funktion Resultat in EAX mov [ebp-$04], eax // i := EAX lea eax, [ebp-$04] // EAX := @i // Adresse von "i" in EAX call 0043C6A8 // Prozedur -------------- Also! Ich habe extra alles kommentiert. Bei Prozedur() sieht man, daß nicht eine lokale Variable auf dem Stack, sondern die Speicheradresse an der "i" liegt, verändert wird. Wenn man so will, wird folgendes übergeben:
Bei Funktion() hingegen wird zuerst der übergebene Wert, welcher auf dem Stack als "lokale Variable" (lokale Variablen und Parameter sind eigentlich intern das Gleiche) liegt, in das Register EAX übergeben. Da ordinale Rückgabewerte bei den Aufrufkonventionen STDCALL und REGISTER jeweils in EAX zurückgegeben werden, wird EAX nur noch inkrementiert. WÜRDE MAN ALSO: Prozedur(i:Integer) schreiben, dann wäre "i" eine "lokale Variable" und damit ginge der Rückgabewert verloren! Hingegen bei obigem Beispiel (als Wieder- holung) wird direkt PInteger(@i)^:=PInteger(@i)^+1; modifiziert. Jetzt klar? Du modifizierst nämlich direkt eine "globale" Variable. Für den Compiler ist das gleich ... der kann jede Speicherstelle so referenzieren, auch wenn im Delphi-Source die Variable "i" innerhalb von Button1Click() eine "lokale" Variable ist. |
Zitat:
Code:
Das ist nicht als CONST deklariert, stimmt, aber trotzdem nicht variabel, außerdem macht es keinen Sinn solch eine Funktion zu verwenden. Es ist halt ein Beispiel.
function Test : integer;
begin result := 5; end; Worauf ich hinaus wollte ist folgendes: Angenommen es muß eine Zahl berechnet werden in einem konkreten Fall, z.B. die Mehrwertsteuer. Wo liegt da hier ein Unterschied ? Zwischen dem hier:
Delphi-Quellcode:
und dem :
procedure MWSTproc (netto : real;var brutto : real);
begin brutto := netto * 1.16; end;
Delphi-Quellcode:
Im Endeffekt wird die Zahl berechnet und basta. Und, wie man sieht ist die eigentliche Berechnung genau dieselbe. Ob das nun im AX Register oder sonstwo gespeichert wird, wen interessiert das ?
function brutto (netto : real) : real;
begin brutto := netto * 1.16; end; In beiden Fällen muß sowieso noch eine globalere Variable deklariert werden, um mit dem berechneten Wert zu hantieren.
Code:
Bei Prozeduren würde das hier den Wert liefern (gespeichert in BruttoVar):
var BruttoVar : real;
Code:
bei Funktionen:
MwstProc (netto,BruttoVar
Code:
Der Nachteil von Funktionen ist halt, daß man nur einen Wert zurück erhält, während man bei Prozeduren mehrere VAR - Parameter übergeben kann. Um beim Beispiel zu bleiben:
BruttoVar := brutto (netto);
Delphi-Quellcode:
Diese Prozedur würde ZWEI Zahlen zurückliefern, die man verwenden könnte !
procedure BerechneBruttoRabatt (netto, rabatt: real; var BruttoOhneRabatt,BruttoMitRabatt : real);
begin BruttoOhneRabatt := netto * 1.16; BruttoMitRabatt := (netto - rabatt) * 1.16; end; @Assarbad: Zitat:
1. kryptische Schreibweise (wegen Steinzeit) 2. Groß- und Kleinschreibung 3. ganz gravierend :!: folgender Code wäre möglich (in Delphi Syntax):
Delphi-Quellcode:
4. usw. :mrgreen:
procedure Test;
begin showmessage (st); VAR st : string; end; |
Hallo Hansa,
Zitat:
Dass Du Deinen Wert wie in Deinem Beispiel sowohl mit einer Prozedur als auch einer Funktion erhalten kannst, daran hat von Anfang an niemand gezweifelt. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:32 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz