AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Rückgabewerte von Funktionen und Prozeduren
Thema durchsuchen
Ansicht
Themen-Optionen

Rückgabewerte von Funktionen und Prozeduren

Ein Thema von Hansa · begonnen am 3. Jul 2003 · letzter Beitrag vom 4. Jul 2003
Antwort Antwort
Seite 3 von 4     123 4      
CepheidenX

Registriert seit: 11. Mär 2003
43 Beiträge
 
Delphi 6 Professional
 
#21
  Alt 3. Jul 2003, 19:22
procedure Test (pi: PInteger); zusammen mit
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.
function Test (pi: PInteger);
Zynismus ist der geglückte Versuch, die Welt so zu sehen, wie sie wirklich ist.
  Mit Zitat antworten Zitat
Benutzerbild von Sanchez
Sanchez

Registriert seit: 24. Apr 2003
Ort: Neumarkt Stmk
892 Beiträge
 
Delphi XE6 Enterprise
 
#22
  Alt 3. Jul 2003, 19: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
Daniel
  Mit Zitat antworten Zitat
Chewie

Registriert seit: 10. Jun 2002
Ort: Deidesheim
2.886 Beiträge
 
Turbo Delphi für Win32
 
#23
  Alt 3. Jul 2003, 19:30
Zitat von CepheidenX:
procedure Test (pi: PInteger); zusammen mit
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.
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.
Martin Leim
Egal wie dumm man selbst ist, es gibt immer andere, die noch dümmer sind
  Mit Zitat antworten Zitat
CepheidenX

Registriert seit: 11. Mär 2003
43 Beiträge
 
Delphi 6 Professional
 
#24
  Alt 3. Jul 2003, 19:34
@Chewie
Weis ich doch, mein Post sollte als Ergänzung zu deinem gesehen werden

Ich denkmal mittlerweile ist das auch geklärt, oder?
Zynismus ist der geglückte Versuch, die Welt so zu sehen, wie sie wirklich ist.
  Mit Zitat antworten Zitat
Chewie

Registriert seit: 10. Jun 2002
Ort: Deidesheim
2.886 Beiträge
 
Turbo Delphi für Win32
 
#25
  Alt 3. Jul 2003, 20:07
Zitat von CepheidenX:
@Chewie
Weis ich doch, mein Post sollte als Ergänzung zu deinem gesehen werden
Mein Ego kanns halt nicht ertragen, wenn andere sagen, ich hätte einen Fehler gemacht
Martin Leim
Egal wie dumm man selbst ist, es gibt immer andere, die noch dümmer sind
  Mit Zitat antworten Zitat
Hansa

Registriert seit: 9. Jun 2002
Ort: Saarland
7.554 Beiträge
 
Delphi 8 Professional
 
#26
  Alt 3. Jul 2003, 20:22
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 ?
Gruß
Hansa
  Mit Zitat antworten Zitat
Chewie

Registriert seit: 10. Jun 2002
Ort: Deidesheim
2.886 Beiträge
 
Turbo Delphi für Win32
 
#27
  Alt 3. Jul 2003, 22:11
Hä? Du hast die 5 nicht als Konstante deklariert
Martin Leim
Egal wie dumm man selbst ist, es gibt immer andere, die noch dümmer sind
  Mit Zitat antworten Zitat
Gast
(Gast)

n/a Beiträge
 
#28
  Alt 3. Jul 2003, 23: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(iInteger); 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.
  Mit Zitat antworten Zitat
Hansa

Registriert seit: 9. Jun 2002
Ort: Saarland
7.554 Beiträge
 
Delphi 8 Professional
 
#29
  Alt 4. Jul 2003, 07:42
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 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.
Gruß
Hansa
  Mit Zitat antworten Zitat
Daniel
(Co-Admin)

Registriert seit: 30. Mai 2002
Ort: Hamburg
13.920 Beiträge
 
Delphi 10.4 Sydney
 
#30
  Alt 4. Jul 2003, 07:47
Hallo Hansa,

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. 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.
Daniel R. Wolf
mit Grüßen aus Hamburg
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 3 von 4     123 4      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:25 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