Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Rückgabewerte von Funktionen und Prozeduren (https://www.delphipraxis.net/6221-rueckgabewerte-von-funktionen-und-prozeduren.html)

Hansa 3. Jul 2003 15:20


Zitat:

Zitat von sakura
Na dann ändere mal. Eine Prozedure kann keinen Rückgabewert haben.

Da bitte ich aber mal um Erläuterung.

[================================================]
Dieser Thread wurde von folgendem Thread abgetrennt, da die Inhalte beide diskussionswürdig sind, allerdings verschieden Voraussetzungen mit sich bringen.
http://www.delphipraxis.net/viewtopic.php?t=6884

Mit freundlichen Grüßen,
SAKURA

sakura 3. Jul 2003 15:36

Zitat:

Zitat von Hansa
Da bitte ich aber mal um Erläuterung.

Was genau willst Du hören. var-Parameter sind keine Rückgabewerte ;-)

Ich quotiere doch glatt noch einmal den Delphi-Language Guide:
Zitat:

Code:
[b]Prozedurdeklarationsabschnitt [/b]-> Prozedurdeklaration
                              -> Funktionsdeklaration
[b]Prozedurdeklaration [/b]-> Prozedurkopf ';' [Direktive] [Portabilitäts-Direktive]
                       Block ';'
[b]Funktionsdeklaration [/b]-> Funktionskopf ';' [Direktive] [Portabilitäts-Direktive]
                     Block ';'
[b]Funktionskopf [/b]-> FUNCTION Bezeichner [Formale Parameter] ':' (Einfacher Typ | STRING)
[b]Prozedurkopf [/b]-> PROCEDURE Bezeichner [Formale Parameter]
[b]Formale Parameter [/b]-> '(' Formaler Parameter ';'. ')'
[b]Formaler Parameter [/b]-> [VAR | CONST | OUT] Parameter
[b]Parameter [/b]-> Bezeichnerliste [':' ([ARRAY OF] Einfacher Typ | STRING | DATEI)]
          -> Bezeichner ':' Einfacher Typ '=' Konstanter Ausdruck

Darin ist der Aufbau einer Prozedur und einer Funktion sehr gut erklärt. Beide können optional eine Parameterliste haben. Eine Funktion liefert einen Ergebniswert zurück, wohingegen eine Prozedure dieses nicht tut. Beide können jedoch variable Parameter haben, welche auch Ausgabewerte aufnehmen können.

...:cat:...

Hansa 3. Jul 2003 15:44

Ach du Schande, Sakura bringt tatsächlich die Grammatik. Hätte ich das vorher gewußt. :mrgreen:

Aber was hindert einen daran, den VAR Paramter als Rückgabewert zu benutzen. Wie bei einer Funktion :?:

sakura 3. Jul 2003 16:00

Wie gesagt, ich habe geschreiben, das man var-Parameter nutzen kann, aber das sind keine Prozedur-Rückgabe werden, es sind halt "[in|out] Parameter", welche einen Rückgabewert aufnehmen kann. Es ist ein kleiner, feiner Unterschied.

...:cat:...

Hansa 3. Jul 2003 16:19

Dann schreibe doch wenigstens, warum. :shock: Man kann eine Prozedur nicht so übergeben:
Delphi-Quellcode:
var i : integer;

i := procedure Iwert

aber schon als i := IFunction, wobei:

Function IFunction : integer;
Pseudocode halt :mrgreen:

sakura 3. Jul 2003 16:24

Hansa, Du hast mit Deinem Ansatz aber völlig am Problem vorbei manövriert. Es geht hier um "Prozedurvariablen", welche eigentlich Pointer sind. Damit würde auch folgender Code problemlos gehen (Zuweisung einer Prozedur auf eine "Prozedurvariable")
Delphi-Quellcode:
procedure Oehm(X, C: Integer);
begin
  ShowMessage(IntToStr(X + C));
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  F: procedure (A, B: Integer);
begin
  F := Oehm;
  F(1, 2);
end;
Dabei wird Owhm F zugewiesen. Oehm ist eine Prozedur.

...:cat:...

CepheidenX 3. Jul 2003 16:36

Worum gehts denn hier eigentlich noch? Sicher doch nicht um den unterschied zwischen Funktionen (gibt einen Funktionswert zurück) und Prozeduren (gibt keinen Funktionswert zurück).
Das ist doch wieder so ein Punkt den C-Programmierer nehemn um Pascal bzw Delphi schlecht zumachen. Denn sie meinen es ist verwirrend da zu unterscheiden, immerhin gibt es in C ja nur Funktionen (mit und ohne Rückgabewert).

Was die Parameterübergabe bei Prozeduren angeht, da sollte man erstmal in die Online Hilfe schauen :-)
Stichwort: Parameter

Hansa 3. Jul 2003 16:42

Zitat:

...Funktionen (gibt einen Funktionswert zurück) und Prozeduren (gibt keinen Funktionswert zurück)...
Eine Prozedur gibt keinen Funktionswert zurück, aber einen VAR-Parameter. Eine Function gibt nur EINEN zurück, Prozeduren mehrere.

CepheidenX 3. Jul 2003 16:52

Das sind aber Parameter! da steckt ein andere Mechanismus hinter.

In Delphi gibt es 4 Parameterformen (Wert-, (Var) Variablen-, (const) Konstanten- oder (out) Ausgabeparameter) sie geben an wie die Variablen in der Routine behandelt wird.

Bei VAR-Parametern wird KEINE neue Variable erzeugt, wie bei den anderen. im Prinzip wird nur ein Zeiger übergeben. Somit haben verönderungen in der Subroutine direkte Auswirkungen auf die Variable.

Im Prinzip würde das auch bei Funktionen gehen. Aber Borland hat das eben nicht so vorgesehen.

Hansa 3. Jul 2003 17:12

Zitat:

Zitat von CepheidenX
...Bei VAR-Parametern wird KEINE neue Variable erzeugt, wie bei den anderen...

Kommst Du etwa aus der falschen Richtung ? Oder ich ?

CepheidenX 3. Jul 2003 17:19

@Hansa
Ich weis ja nicht was du genau willst.
Aber bei der Übergabe von normalen Parametern in Delphi/Pascal wird (vom compiler, also im Hintergrund) eine neue lokale Variable, also ein Integer oder String ...) für die SubRoutine erzeugt. Wenn Das steuerwort var benutzt wird ist das nicht der Fall.
Naja fast, es wird nur ein Zeiger erzeugt der auf die Variable in der übergeordneten Routine zeigt.
Wie gesagt bekommt der Programmierer davon nichts mit.
Was du mit
Zitat:

Kommst Du etwa aus der falschen Richtung ? Oder ich ?
meinst versteh ich nicht.

Hansa 3. Jul 2003 17:25

ich verstehe das genauso wenig, wie Du. 8) Wenn ich folgenden Code habe:

Delphi-Quellcode:
procedure Test (VAR i : integer);
  begin
    i := 5;
  end;
was steht dann hier drin ? :
Delphi-Quellcode:
begin
  showmessage (IntToStr (Test (8));
end;

CepheidenX 3. Jul 2003 17:32

Du meinst wie ShowMessage deklariert ist?
Delphi-Quellcode:
procedure ShowMessage(const Msg: string);
kannst du auch selber nachschauen :-)

Edit: Ich versteh nicht ganz worauf du hinaus willst

Hansa 3. Jul 2003 17:39

Delphi-Quellcode:
unit TestUnit;

Interface

procedure Test (VAR i : integer);

implementation

procedure Test (VAR i : integer);
  begin
    i := 5;
  end;

end;
was steht dann hier drin ? :
Delphi-Quellcode:
program TestProgramm;

uses TestUnit,.....

begin
  showmessage (IntToStr (Test (8));
end;
??????

CepheidenX 3. Jul 2003 17:44

Könntest du dich bitte so ausdrücken das man versteht was du willst?

Irgendwelchen kommentarlosen Quelltext posten nenne ich nicht verständlich oder klar ausdrücken. Und ein "was steht dann hier drin ? :" bringt es auch nicht wirklich. :roll:
Eventuell bin ich ja schwer von Begriff, also hab Verständnis.

Hansa 3. Jul 2003 17:55

Viel einfacher gehts wirklich nicht. :|

Das ist wahrscheinlich eines der kleinsten Programme der Welt. Mir fällt jedenfalls nicht ein, wie es noch kleiner werden könnte. Läßt Du das Programm laufen, was wird dann angezeigt? 5 oder 8 ???

Das ist ein Rätsel, wo die Lösung gleich mitgeliefert wird. :mrgreen:

Chewie 3. Jul 2003 18:01

Es wird gar nichts angezeigt, denn du kannst das Programm nicht kompilieren. InttoStr() erwartet als Parameter einen Integer, die Prozedur gibt aber keinen Integer als Rückgabewert zurück.
Sie hat keinen Rückgabewert.

Hansa 3. Jul 2003 18:08

Zitat:

Zitat von Chewie
... InttoStr() erwartet als Parameter einen Integer, die Prozedur gibt aber keinen Integer als Rückgabewert zurück.

Code:
procedure Test (VAR i : integer);
  begin
    i := 5;
  end;
Wieso ist da kein Rückgabewert ???

CepheidenX 3. Jul 2003 18:08

1. "was steht dann hier drin ? :" Sagt für mich nicht aus, dass ich Dir sagen soll was nach ausführen deines Programm-Codes af dem Bildschirm ausgegeben wird.

2. ist dein Quelltext fehlerhaft! Ausser du bringst Delphi bei, Zahlen als Variablennamen zu interpretieren. Du kannst einer Prozedur die ein Var-Parameter verlangt keinen Zahlenwert übergeben.

Meinen perönlichen Kommentar verkeif ich mir mal. :|

Chewie 3. Jul 2003 18:16

Zitat:

Zitat von Hansa
Code:
procedure Test (VAR i : integer);
  begin
    i := 5;
  end;
Wieso ist da kein Rückgabewert ???

Also gut :mrgreen:

"Rückgabewert" bedeutet, dass die Rückgabe der Funktion nach Ablauf des Programmblocks (=Funktion) in das Register EAX geschrieben wird. Bei einer Funktion ist da was drin, bei einer Prozedurr wird da nichts reingeschrieben.
Ein Var-Parameter ist kein Rückgabewert. Anstatt
Delphi-Quellcode:
procedure Test (VAR i: Integer);
könntest du auch schreiben:
Delphi-Quellcode:
procedure Test (pi: PInteger);
VAR bedeutet, dass nicht der Speicherblock, den die Variable belegt, an die Funktion übergeben wird, sondern nur die Startadresse dieses Blocks. Die Funktion kann anhand dieser Adresse in den Speicherblock der Variablen schreiben, und somit kann sich der Wert derr Variablen ändern.

CepheidenX 3. Jul 2003 18:22

Delphi-Quellcode:
procedure Test (pi: PInteger);
zusammen mit
Delphi-Quellcode:
showmessage (IntToStr (Test (8));
Geht aber auch nicht! Denn IntToStr velangt einen Parameter. Und den kann eine Prozedur nicht liefern.

Desshalb müsste die Routine Test schon eine Funktion sein.
Delphi-Quellcode:
function Test (pi: PInteger);

Sanchez 3. Jul 2003 18:22

@ Hansa
zu deiner Frage: Wieso ist da kein Rückgabewert.

Eine Funktion liefert einen Rückgabewert

Delphi-Quellcode:
function Test : integer;
begin
    result := 5;
end;
Diese Funktion hat einen Rückgabewert vom Typ Integer mit dem Wert 5.

Eine Prozedur hat keinen Rückgabewert

Delphi-Quellcode:
procedure Test (VAR i : integer);
begin
    i := 5;
end;
Diese Prozedur hat keinen Rückgabewert, sondern sie pinselt hier nur den Wert 5 in die Adresse der Variable die du ihr Übergibst.

Deshalb kannst du auch nicht das machen:

Delphi-Quellcode:
begin
  showmessage (IntToStr (Test (8));
end;
Das würde funktionieren:

Delphi-Quellcode:
var i : integer;
begin
  i := 2;
  Test (i);
  showmessage (IntToStr (i);
end;
In der Messagebox würde eine 5 stehen.

Alles klar?

mfg Daniel

Chewie 3. Jul 2003 18:30

Zitat:

Zitat von CepheidenX
Delphi-Quellcode:
procedure Test (pi: PInteger);
zusammen mit
Delphi-Quellcode:
showmessage (IntToStr (Test (8));
Geht aber auch nicht! Denn IntToStr velangt einen Parameter. Und den kann eine Prozedur nicht liefern.

Desshalb müsste die Routine Test schon eine Funktion sein.
Delphi-Quellcode:
function Test (pi: PInteger);

Klar, in diesem Fall geht es nicht. Ich wollte nur zeigen, dass unter Verwendung von var nur die Adresse einer Variablen übergeben wird.

CepheidenX 3. Jul 2003 18:34

@Chewie
Weis ich doch, mein Post sollte als Ergänzung zu deinem gesehen werden :D

Ich denkmal mittlerweile ist das auch geklärt, oder?

Chewie 3. Jul 2003 19:07

Zitat:

Zitat von CepheidenX
@Chewie
Weis ich doch, mein Post sollte als Ergänzung zu deinem gesehen werden :D

Mein Ego kanns halt nicht ertragen, wenn andere sagen, ich hätte einen Fehler gemacht :mrgreen:

Hansa 3. Jul 2003 19:22

Zitat:

Zitat von Sanchez0815
Eine Prozedur hat keinen Rückgabewert
Delphi-Quellcode:
var i : integer;
begin
  i := 2;
  Test (i);
  showmessage (IntToStr (i);
end;
In der Messagebox würde eine 5 stehen.

Alles klar?

Ja klar, alles. Genau das habe ich geschrieben. C++ läßt halt grüßen an die Verwandtschaft. Und was wäre, wenn ich die 5 nicht innerhalb der Prozedur als Konstante verwendet hätte ??? Was würde dann angezeigt ? :mrgreen:

Chewie 3. Jul 2003 21:11

Hä? Du hast die 5 nicht als Konstante deklariert :?:

Gast 3. Jul 2003 22:24

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:
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;
Etwas Pseudo-Code:
Code:
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
--------------
Uns interessieren die Stellen zwischen den: "~~~~~~~~~~~~~~".

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:
  • @i ... hätte man also beispielsweise geschrieben Prozedur(i:PInteger); so wäre dies das Selbe!!!
  • @i sollte bekannt sein, es ist die Adresse an der "i" liegt.

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.

Hansa 4. Jul 2003 06:42

Zitat:

Zitat von Chewie
Hä? Du hast die 5 nicht als Konstante deklariert :?:

Das war vielleicht nicht leicht zu verstehen, ich meine das hier:

Code:
function Test : integer;
begin
  result := 5;
end;
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.

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:
procedure MWSTproc (netto : real;var brutto : real);
  begin
    brutto := netto * 1.16;
  end;
und dem :

Delphi-Quellcode:
function brutto (netto : real) : real;
  begin
    brutto := netto * 1.16;
  end;
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 ?

In beiden Fällen muß sowieso noch eine globalere Variable deklariert werden, um mit dem berechneten Wert zu hantieren.

Code:
var BruttoVar : real;
Bei Prozeduren würde das hier den Wert liefern (gespeichert in BruttoVar):

Code:
MwstProc (netto,BruttoVar
bei Funktionen:

Code:
BruttoVar := brutto (netto);
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:

Delphi-Quellcode:
procedure BerechneBruttoRabatt (netto, rabatt: real; var BruttoOhneRabatt,BruttoMitRabatt : real);
  begin
    BruttoOhneRabatt := netto * 1.16;
    BruttoMitRabatt := (netto - rabatt) * 1.16;
  end;
Diese Prozedur würde ZWEI Zahlen zurückliefern, die man verwenden könnte !

@Assarbad:
Zitat:

Zitat von Assarbad
C wurde nämlich erfunden um Programmierern das Leben schwer zu machen.

Ist das Dein Ernst oder ironisch gemeint? C hat meiner Meinung nach gegenüber Delphi folgende Nachteile:
1. kryptische Schreibweise (wegen Steinzeit)
2. Groß- und Kleinschreibung
3. ganz gravierend :!: folgender Code wäre möglich (in Delphi Syntax):

Delphi-Quellcode:
procedure Test;
begin
  showmessage (st);
  VAR st : string;
end;
4. usw. :mrgreen:

Daniel 4. Jul 2003 06:47

Hallo Hansa,

Zitat:

Zitat von Hansa
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 ?

...Dich offenkundig nicht. :wink: Aber genau darin liegt einer der technischen Unteschiede zwischen Prozeduren und Funktionen. Assarbard hat es doch in seinem Beispiel dargelegt.
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.

Hansa 4. Jul 2003 07:02

Halte mich eben hier dran :wink: :

Zitat:

Titel: Rückgabewerte von Funktionen und Prozeduren
Was da technisch jetzt genau passiert, interessiert mich in der Regel wirklich nicht. Aber vielleicht kann mir mal jemand erklären, wann es zwingend nötig ist eine Funktion bzw. Prozedur zu verwenden und warum. 8) Worauf Assarbad hinaus will, ist wahrscheinlich das hier :
Delphi-Quellcode:
procedure Test (CONST r : real);
und

Delphi-Quellcode:
procedure Test (VAR r : real);
Wie heißt der Vorgänger von Pascal (Wirth) noch ? War es Algol ?

sakura 4. Jul 2003 08:06

@Hansa: Jetzt will ich Dich erst einmal bitten nachzudenken ;-) Abgesehen von Deinem ursprünglich gelieferten Beispiel, welches völlig inkorrekt war, hast Du auch weitere Falsch-Aussagen gemacht. Die gravierendste ist jene, die Du immer wieder anbringst:
Zitat:

Zitat von Hansa
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.

Wieso sollte man bei Funktionen keine var-Parameter übergeben können? Das macht die WinAPI stets und ständig, von Delphi auf kannst Du drauf zugreifen. Ein einfaches Beispiel:
Delphi-Quellcode:
function FreeModule(var hLibModule: HINST): BOOL;
function InterlockedIncrement(var Addend: Integer): Integer; stdcall;function GetExitCodeProcess(hProcess: THandle; var lpExitCode: DWORD): BOOL; stdcall;
// u.s.w. u.s.f.
Also ist dieses Argument schon in einmal nichtig.

Ein weiterer Vorteil von Funktionen über Prozeduren ist, deren Rückgabewerte direkt in Berechnungen einbinden zu können. Es besteht nicht der Zwang eine separate Variable zu deklarieren, bevor ich diese nur einmal verwende. Beispiel gefällig? Okay, anhand der Funktionen FileExists und DeleteFile:
Delphi-Quellcode:
 // die wohl viel elegantere Lösung via Funktion
// function FileExists(const FileName: string): Boolean;
// function DeleteFile(const FileName: string): Boolean;
begin
  if FileExists('C:\Temp\LöschMich.txt') then
    if not DeleteFile('C:\Temp\LöschMich.txt') then
      ShowMessage('Die Datei konnte nicht gelöscht werden');
end;

// hättest Du es so lieber???
// HYPOTHETISCH
// procedure FileExists(const FileName: string; var Result: Boolean);
// procedure DeleteFile(const FileName: string; var Success: Boolean);
var
  Status: Boolean;
begin
  FileExists('C:\Temp\LöschMich.txt', Status);
  if Status then
  begin
    DeleteFile('C:\Temp\LöschMich.txt', Status);
    if not Status then
      ShowMessage('Die Datei konnte nicht gelöscht werden');
  end;
end;
Das mal als Beispiel für den Nutzen fon Funktionen. Und das Argument der var-Parameter zieht nicht ;-) Erinnere Dich an den Auszug der Delphi-Grammatik-Regeln. Die geben an, daß die Parameter-Listen Definition für Prozeduren und Funktionen identisch sind. Was in der einen geht, geht auch in der anderen.
Code:
[b]Funktionskopf [/b]-> FUNCTION Bezeichner [Formale Parameter] ':' (Einfacher Typ | STRING)
[b]Prozedurkopf [/b]-> PROCEDURE Bezeichner [Formale Parameter]
[b]Formale Parameter [/b]-> '(' Formaler Parameter ';'. ')'
[b]Formaler Parameter [/b]-> [VAR | CONST | OUT] Parameter
[b]Parameter [/b]-> Bezeichnerliste [':' ([ARRAY OF] Einfacher Typ | STRING | DATEI)]
          -> Bezeichner ':' Einfacher Typ '=' Konstanter Ausdruck
Noch ein weiterer Vortail eine Funktion gegenüber einer Prozedur ist, wenn man nur einen Rückgabewert erwartet, die Geschwindigkeit. Durch die Rückgabe dieses Wertes im (E)AX Register, sind den möglchen Optimierungen durch den Compiler viel mehr Raum gegeben.
Zitat:

Zitat von Hansa
Angenommen es muß eine Zahl berechnet werden in einem konkreten Fall, z.B. die Mehrwertsteuer. Wo liegt da hier ein Unterschied ?
Delphi-Quellcode:
procedure MWSTproc (netto : real;var brutto : real);
  begin
    brutto := netto * 1.16;
  end;
Delphi-Quellcode:
function brutto (netto : real) : real;
  begin
    brutto := netto * 1.16;
  end;

Zitat:

Zitat von Hansa
In beiden Fällen muß sowieso noch eine globalere Variable deklariert werden, um mit dem berechneten Wert zu hantieren.

Ich erinnere an mein gerade angeführtes Beispiel mit FileExists, ich kann die Funktion direkt in weitere Berechnungen einsetzen und muss nicht eine weitere Variable einführen, um den Wert zu hantieren.

Bevor Du jetzt die Diskussion fortsetzt, biite ich Dich, Dir mal den Delphi-Language Guide in die Hand zu nehmen und Dich über die (weiteren) Unterschiede von Prozedure und Funktion zu informieren.

...:cat:...

Hansa 4. Jul 2003 08:27

ach, wie ist das herrlich. Was liebe ich solche Grundsatzdiskussionen. 8) Könnte fast ein C++ - Forum sein. :mrgreen: Schlimm ist, daß Sakura Recht hat. :lol: Bei Funktionen können auch mehrere VAR Parameter übergeben werden. Und sie können, wie er richtig sagt, direkt für weitere Berechnungen benutzt werden.

Für mich ist letzteres der einzige Grund, Funktionen zu benutzen. Ansonsten ist es mir egal. Compiler-Optimierungen? Da möge mal einer eine Zahl nennen. Wieviel % macht es aus, wenn statt Prozeduren Funktionen oder umgekehrt verwendet werden?

sakura 4. Jul 2003 08:45

Zitat:

Zitat von Hansa
Compiler-Optimierungen? Da möge mal einer eine Zahl nennen. Wieviel % macht es aus, wenn statt Prozeduren Funktionen oder umgekehrt verwendet werden?

Lässt sich schwer in Zahlen fassen. Und ich gebe Dir recht, meist ist das auch nebensächlich. Allerdings, wenn Du wie ich, an einer Software arbeitest, die mehrere 1000 Anfragen pro Minute, manchmal über 1000 in einer Sekunde, abarbeiten muss, dann wird jeder noch so geringe Geschwindikeitsvorteil wichtig. Deshalb habe ich das auch mit angebracht. Bei Desktop-Software mit einem "lahmen" User an einer "schnellen" Machine kommt es auf die paar Millisekunden nicht an, richtig.

...:cat:...

Hansa 4. Jul 2003 09:05

Na also, auch hier hat jeder Recht :lol:, aber eines fehlt noch (insbesondere für Anfänger gefährlich) : Manchmal macht es eher Sinn, einen berechneten Wert in einer Variablen zu speichern, anstatt ihn dauernd neu zu berechnen. Aus Sakuras Millisekunden werden sonst tatsächlich spürbare Wartezeiten. Dies gilt insbesondere für Datenbank-Zugriffe innerhalb einer Funktion.


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:22 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