Hallo
Ich versuche eine erste einfache Procedure in Lazarus in
Pascal-Programmiersprache zum laufen zu bringen aber irgendwas mit den
"end" stimmt noch nicht, ich dachte ich kenne die Regeln aber brauche
jetzt eure Hilfe.
das Programm ist folgendees:
g457 schrieb:> War bei Pascal nicht irgendwas(tm) mit '.' beim letzten 'end' oder> sowas?
und jedes end braucht ein begin, ausser bei uint Initialisierung.
Pascal schrieb:> Procedure EinfacheProcedure(a,b:real;> out Ergebnis1, Ergebnis2: real);> begin> Ergebnis1:=a+b;> Ergebnis2:=a-b>> end;
Um ein Ergebnis zu liefern, müsste es heissen
1
Function Ergebnis1 (a,b : real) : real;
2
begin
3
Ergebnis1 := a+b;
4
end;
Aber mit 2 Ergebnissen bist du sowieso auf dem Holzweg, eine Function
hat nur eines, eben den Wert der Function. Entweder du definierst 2
Functions oder du lässt es bei der Procedure, die auf für sie globale
Variablen Ergebnsi1, Ergebnis 2 zugreift, was nicht sehr portabel ist un
deshalb etwas verpönt - aber korrekt.
Gruss Reinhard
Reinhard Kern schrieb:> Aber mit 2 Ergebnissen bist du sowieso auf dem Holzweg, eine Function> hat nur eines, eben den Wert der Function. Entweder du definierst 2> Functions oder du lässt es bei der Procedure, die auf für sie globale> Variablen Ergebnsi1, Ergebnis 2 zugreift, was nicht sehr portabel ist un> deshalb etwas verpönt - aber korrekt.
Schwachwug hoch Zehn ;-)
Ergebnisse können als var deklariert per Parameter übergeben werden.
Aber die Frage war eine andere:
BeleFischer schrieb:> aber irgendwas mit den> "end" stimmt noch nicht, ich dachte ich kenne die Regeln aber brauche> jetzt eure Hilfe.
Hallo,
warum sollte mir eine Funktion nicht mehrere Ergebnisse in einem
eigenen Type (hier z.B. Array) zurückgeben können ?
(jetzt mal unabhängig davon ob guter oder schlechter Programmierstil)
BeleFischer schrieb:> Ich versuche eine erste einfache Procedure in Lazarus in> Pascal-Programmiersprache zum laufen zu bringen aber irgendwas mit den> "end" stimmt noch nicht
Es stimmt ne Menge anderes auch bloß nicht.
Also:
program Project1;
uses
{ hier kommt die Liste der benutzten Units rein, Beispiele: }
Windows, DOS, UNIX, SysUtils, MyKrempel, DiesUndDas;
Procedure EinfacheProcedure(a,
b : real;
var Ergebnis1 : real;
var Ergebnis2 : real);
begin
Ergebnis1:=a+b;
Ergebnis2:=a-b
end;
{ und hier haste den Hauptteil vergessen }
var
Blabla : real;
lalala : real;
begin
EinfacheProcedure(123, 345, Blabla, lalala);
writeln('auf meinem Miste wuchsen ',Blabla,' Früchte an ',lalala,
' Bäumen');
end.
Vergiß den Punkt nicht hinter dem letzten end
und schreib nicht solche scheußlichen Prozeduren. Für Rückgabewerte
nimmt man FUNCTION.
W.S.
W.S. schrieb:> und schreib nicht solche scheußlichen Prozeduren. Für Rückgabewerte> nimmt man FUNCTION.
Das sieht nicht jeder so. Oft gibt der Rückgabewert einer function eine
Aussage über Versagen oder nicht, z. Bsp. Wertebereich verlassen,
Division durch 0, usw. Du hast selber ein schönes Bsp. geschrieben:
Der, der die Frage liest schrieb:> Du hast selber ein schönes Bsp. geschrieben:
Nee, mein Lieber, das war nur des Zitates willen. Ich hab nur das
ominöse 'out' entfernt. Schau:
BeleFischer schrieb:> Procedure EinfacheProcedure(a,b:real;> out Ergebnis1, Ergebnis2: real);
W.S.
Hallo,
Jede IDE wie lazarus,fp ( syntaxcheck ), geany , etc pp hätte über das
fehlende end. gemosert/es angezeigt.
Wer hat denn etwas gegen out Parameter?
Siehe http://www.freepascal.org/docs-html/ref/refsu57.html
Wer will den für jedes blabalbal und lalala eine extra Typ anlegen.
Ein guter Prozedurname hilft doch eher weiter, ala
Horst Hahn schrieb:> Wer hat denn etwas gegen out Parameter?
Ich.
Ist ne nette Spielerei, aber bei gründlicher Betrachtung nur etwas, das
schlechten Programmierstil befördert.
W.S.
W.S. schrieb:> Ist ne nette Spielerei, aber bei gründlicher Betrachtung nur etwas, das> schlechten Programmierstil befördert.
Ich habe so meine Zweifel daran, daß Du weißt, wovon Du da redest.
Rufus Τ. Firefly schrieb:> Ich habe so meine Zweifel daran, daß Du weißt, wovon Du da redest.
Hehe, du wolltest mal wieder ein bissel stänkern, gelle?
Aber ich bin ja ein netter und positiv eingestellter Mensch und deshalb
erkläre ich dir das mal:
Also, "var" wurde mal eingeführt, um Programm und Stack bei umfänglichen
Argumenten einer Funktion zu entlasten. Dabei wurde leider ein im
Prinzip unerwünschter Seiteneffekt mit eingeführt, denn dadurch war es
möglich, mutwillig oder versehentlich Veränderungen an einem so
deklarierten Argument zu bewirken. Es wurde dann mit "const"
nachgebessert, aber das greift nur dort, wo die Programmierer es auch
tatsächlich benutzen. Die Einführung von "out" ist zwar konsequent und
stellt zumindest eine Art 'Achtungs-Schild' dar, aber sie befördert eben
auch dessen Verwendung und damit einen Programmierstil, wo das Ausnutzen
des Seiteneffektes nicht die seltene Notlösung eines Problems ist,
sondern zum generellen Stil der Programmierer sich entwickelt. Siehe
übliche Programmierstile bei C.
Weitaus besser wäre es, die betreffenden Daten zu einem Objekt zu machen
und die Funktion zu einer Methode dieses Objektes. Das wäre ein Schritt
in die richtige Richtung. Pascal bietet heutzutage diese Möglichkeit,
man kann damit Daten sinnvoll kapseln und unübersichtliche Zusammenhänge
vermeiden, die ansonsten gar zu häufig Ursache schwer zu findender
Laufzeitfehler sind.
W.S.
W.S. schrieb:> Also, "var" wurde mal eingeführt, um Programm und Stack bei umfänglichen> Argumenten einer Funktion zu entlasten.
Das glaube ich nicht (um es genau zu wissen, müsste man allerding Herrn
Wirth fragen). Wenn es so wäre, würde das Schlüsselwort nicht "var",
sondern bspw. "ref" (wegen call by reference) heißen.
> Dabei wurde leider ein im Prinzip unerwünschter Seiteneffekt mit> eingeführt, denn dadurch war es möglich, mutwillig oder versehentlich> Veränderungen an einem so deklarierten Argument zu bewirken.
Und eben weil damit Änderungen des Arguments möglich und auch vorgesehen
sind, wurde als Schlüsselwort "var" (variable=veränderlich) genommen.
> Es wurde dann mit "const" nachgebessert, aber das greift nur dort, wo> die Programmierer es auch tatsächlich benutzen.
Mit "const" sichert der Programmierer dem Compiler nur zu, dass der
Parameter innerhalb des Unterprogramms nicht verändert wird. Damit hat
der Compiler die freie Wahl, das Argument per Wert oder per Referenz zu
übergeben, da es bei korrekter Programmierung keinen semantischen Unter-
schied zwischen den beiden Alternativen gibt.
Will man Call-by-Reference aus Effizienzgründen erzwingen, ist (zumin-
dest in Free Pascal) "constref" die richtige Wahl. Da steckt dann auch
tatsächlich das "ref" für Reference drin.
Zusammengefasst:
Jede dieser fünf Methoden hat also ihren speziellen Einsatzzweck.
> Die Einführung von "out" ist zwar konsequent und stellt zumindest eine> Art 'Achtungs-Schild' dar, aber sie befördert eben auch dessen> Verwendung und damit einen Programmierstil, wo das Ausnutzen des> Seiteneffektes nicht die seltene Notlösung eines Problems ist, sondern> zum generellen Stil der Programmierer sich entwickelt. Siehe übliche> Programmierstile bei C.
Solche Konstrukte sind eben vonnöten, wenn in einer Programmiersprache
Funktionen nur einen einzelnen Rückgabewert liefern können. Das ist eine
Design-Schwäche von Pascal, C und auch vielen neueren, davon abgeleite-
ten Sprachen. Als Seiteneffekt würde ich das aber nicht bezeichnen, da
dieser alternative Weg, Funktionsergebnisse zurückzugeben, klar in der
Funktionsdeklaration durch das "var" bzw. "out" dokumentiert ist.
Schlecht ist allerdings, dass man den Unterschied nicht beim Aufruf der
Funktion erkennen kann.
Man kann die Rückgabewerte allenfalls in einer Struktur zusammenfassen,
um die Out- und Var-Parameter zu vermeiden. Das ist aber in vielen
Fällen auch nicht schön, weil man bei jedem Funktionsaufruf erst die
Werte in die Struktur packen und hinterher die Struktur wieder
auseinanderfieseln muss.
> Weitaus besser wäre es, die betreffenden Daten zu einem Objekt zu> machen und die Funktion zu einer Methode dieses Objektes. Das wäre ein> Schritt in die richtige Richtung.
Auch das ist eine Möglichkeit, aber IMHO ebenfalls etwas von hinten
durch die Brust ins Auge ;-)
Wie dieses Problem elegant gelöst wird, zeigt bspw. Python, wo man
einfach schreibt:
1
y,z=f(x)
Eigentlich liefert auch hier die Funktion nur einen einzelnen Rückgabe-
wert, nämlich ein Tupel. Das anschließende Auseinanderfieseln desselben
geschieht aber nicht explizit, sondern impliziet durch Pattern-Matching,
so dass auf Syntaxebene die Funktion tatsächlich zwei Rückgabewerte
liefert.
Yalu X. schrieb:> Das anschließende Auseinanderfieseln desselben> geschieht aber nicht explizit
Wobei das auch so eine Frage ist ob das nun unbedingt sein muss, ob ich
jetzt schreibe:
1
var x;
2
var y;
3
4
x,y = func();
5
6
echo "x="+x+", y="+y;
oder
1
var obj = func();
2
echo "x="+obj.x+", y="+obj.y;
ist nun auch nicht die Welt... Ich habe (zumindest im OO Umfeld) auch
gaaaaaanz selten den bedarf mal mehr als "einen" Wert zurückzugeben
(eigentlich müsste man sagen: einen Typ, da ja der Rückgabewert durchaus
ein Array sein kann).
Und für den Fall kann man sich wenn es einen nun wirklich wurmt auch
einmal eine generelle Tupel/Tripel/... Klasse schreiben.
Yalu X. schrieb:> Das glaube ich nicht (um es genau zu wissen, müsste man allerding Herrn> Wirth fragen).
Kannst du ja: ich hatte da auch Zweifel, aber im Jensen-Wirth steht
ausdrücklich drin, dass var eingesetzt werden kann, um die Belastung von
Stack und Programmcode gering zu halten durch Übergabe per Referenz (von
Pointern redet da keiner). Wirth hatte das also zumindest AUCH im Auge.
Nicht dumm der Mann.
Wer hat's erfunden? Die Schweizer!
Gruss Reinhard
Reinhard Kern schrieb:> im Jensen-Wirth steht ausdrücklich drin, dass var eingesetzt werden> kann, um die Belastung von Stack und Programmcode gering zu halten
Natürlich kann man das "var" auch zur Handoptimierung einsetzen. Die
Frage ist nur, welches welches der beiden Ziele (veränderliche Argumente
zu haben oder die Effizienzsteigerung) das primäre war. Dem Namen nach
zu urteilen sind es eher die veränderlichen Argumente. Die Effizienz-
steigerung ist ein angenehmer Nebeneffekt, den man natürlich ebenfalls
als Feature angepriesen hat.
Oder steht in dem Buch vielleicht drin, dass das "var" nur zur Effi-
zienzsteigerung eingesetzt werden soll?
Auch in meinem Studium, als ich Pascal lernen musste, wurden die beiden
Anwendungsmöglichkeiten von "var" in dieser Reihenfolge vorgestellt.
Genauer gesagt, hat der Professor nur die Anwendung für veränderliche
Argumente vorgestellt. Später, in den Übungen, hat uns dann die Tutorin
eröffnet, dass das ein cooler Trick ist, um Unterprogrammaufrufe zu
beschleunigen.
Aber eigentlich ist es ja auch egal, was die ursprüngliche Absicht war.
Das Feature wird eben mal so und mal anders genutzt, da seh ich nichts
Böses dabei.
> Wer hat's erfunden? Die Schweizer!
Genau. Es gibt aber auch bei den Bonbons bessere als Ricola ;-)
Yalu X. schrieb:> Das Feature wird eben mal so und mal anders genutzt, da seh ich nichts> Böses dabei.
Es ist ja auch nichte BÖSES, sondern eine Quelle für schlecht
auffindbare Bugs, wenn man nicht wirklich höllisch aufpaßt. Sei doch mal
realistisch: Der größte Teil von Bugs passiert aus irgendwelchen
Schusseligkeiten oder daß man irgendwas übersehen hat - und keiner von
uns kann von sich behaupten, da ganz erhaben drüberzustehen. Schließlich
sind wir Menschen und keine Maschinen.
Es ist also sehr wohl die Frage nach dem eigenen Programmierstil. Ich
bevorzuge - wo es geht - einen Stil, der von Hause aus möglichst so
überschaubar ist, wie die Programmiersprache das zuläßt. Bei plain C hab
ich keine Chance, mit Objekten zu arbeiten und deren Innenleben von der
Außenwelt zu kapseln (um unbeabsichtigte Schnitzer nicht zum Zuge kommen
zu lassen), aber bei Pascal hat man die Möglichkeit - und sie ist
obendrein auch noch gut und angenehm leserlich. Warum also nicht so? Ich
denk mal, im Grunde deiner Seele siehst du das ein bissel ähnlich.
W.S.
W.S. schrieb:> aber bei Pascal hat man die Möglichkeit
Eigentlich da auch nicht. Was Du als Pascal bezeichnest, ist "Object
Pascal", eine Weiterentwicklung von Pascal. Pascal, das ist das, was vor
"Delphi" war.
Mit der gleichen Logik könnte man also auch argumentieren, daß man in C
ebenfalls Objekte nutzen könnte -- denn C++ ist ja auch nur so eine Art
Weiterentwicklung von C.
??? schrieb:> Was hat das mit> der Ausgangsfrage oder variablen Parametern zu tun?
Dass Objekte das Problem der unbeabsichtigten Nebenwirkungen vermeiden
können, das bei var besteht - und weil sowieso alles mit allem
zusammenhängt.
Gruss Reinhard
(interessant wie sich so eine extrem einfache frage, entwickelt...)
>und schreib nicht solche scheußlichen Prozeduren. Für Rückgabewerte>nimmt man FUNCTION.
allein die Existenz von "out" Parameter, beweist ja schon das
Gegenteil..
..
zum VAR, ja da kenne ich auch Leute die das zum
geschwindigkeitsoptimieren verwenden. bei Stings z.B.
real bringt das natürlich fast nix (man spart eine Referenzzählung +/-),
bringt aber einige gefahren...