![]() |
Re: guter stil????
Ist erstens relativ offensichtlich, der Fehler, und mir persönlich auch noch nicht passiert.
|
Re: guter stil????
Hi,
Zitat:
Zitat:
Letztendlich würde ich es so machen:
Delphi-Quellcode:
Die globale Variable m hab' ich erst mal dringelassen, ich hab' ja schon genug anderes kritisiert ;).
// 1) const sorgt eventuell für schnellere Parameterweitergabe, sicher aber dafür,
// dass man sich nicht einfach Variablen überschreibt // 2) ein normaler Integer langt und ist auf 32bit-CPUs schneller berechnet // - StrToInt liefert auch nur einen Integer und keinen int64 // 3) Funktionsname: // Man prüft bei der Verwendung von functions *generell* - Was wird also geprüft? function IstPrim(const n:integer):boolean; var x:integer; begin // Sonderfall 1 beachten if (n = 1) then begin result:=false; exit; end; // Deine Primzahlprüfung hab' ich nicht ganz verstanden. Warum prüfst du nur die Teiler // bis Round(N / 2)? Normalerweise prüft man doch von 2 bis Sqrt(N)! result:=true; for x:=2 to Trunc(Sqrt(N)) do if ((n mod x) = 0) then begin result:=false; exit; end; end; // integer: siehe oben procedure Zerlegen(var OutputLabel:TLabel; const n:integer); var x:integer; begin x:=2; while ((n mod x) <> 0) do Inc(c); // Die Bedingung vorher war Schwachsinn (*sorry*) OutputLabel.Caption:=OutputLabel.Caption+'*'+IntToStr(x); if (not IstPrim(n div x)) then Zerlegen(n div x); m:=m*x; end; procedure TForm1.Button1Click(Sender: TObject); begin m:=1; label2.Caption:=''; if (IstPrim(strtoint(edit1.Text))) then Label2.Caption:=edit1.Text+' ist eine Primzahl!' else begin Zerlegen(Label2, StrToInt(Edit1.Text)); Label2.Caption:=Label2.Caption+'*'+IntToStr(StrToInt(Edit1.Text) div m); end; end; cu |
Re: guter stil????
@Secure:
sorry aber
Delphi-Quellcode:
halte ich fr ziemlich übel.
function IstPrim(const n:integer):boolean;
var x:integer; begin // Sonderfall 1 beachten if (n = 1) then begin result:=false; exit; end; // Deine Primzahlprüfung hab' ich nicht ganz verstanden. Warum prüfst du nur die Teiler // bis Round(N / 2)? Normalerweise prüft man doch von 2 bis Sqrt(N)! result:=true; for x:=2 to Trunc(Sqrt(N)) do if ((n mod x) = 0) then begin result:=false; exit; end; end; 1.) Du vereinfachst durch eigene Annahmen die gewünschte Funktionsweise des Programmieres, indem du enifach mal davon ausgehst das man eh nur Zahlen bis 2^31 testen möchte, statt eben wie im Original mit Int64 zu rechnen. Das ist wohl sehr schlechter Stil. Die Aufgabe des programmieres ist es die Forderungen EXAKT umzusetzen. 2.) dein Source ist fehlerhaft. Was ist mit 0, oder -1 oder allen Zahlen bis -(2^31-1). Übergibt man deiner Funktion einen Integer im Wertebereich der Integer von -2^31 bis 2^31 dann macht sie defacto exakt 50% Fehlerhafte Ausagen. 3.) dein Schreibstil, hm naja. Das Besondere in PASCAL ist es das man Gorß/Klein Schreibung als Mittel zu besseren Lesbarkeit einsetzen kann. Du verzichtest darauf indem du alles klein schreibst. Damit verzichtest du auf Übersichtlickeit. 4.) N. Wirth hat mit Absicht die "Gültigkeit eines Source Blocks" visuell grafisch auch als eingerückter Block mit einem senkrecht untereinander stehendem BEGIN und END eingeführt. Es ist also essentiell das BEGIN und END auf gleicher Einrückungsebene zu schreiben. 5.) was nun ? IstPrim() oder IsPrime() ? aber nicht IsPrim() das ist denglish. 6.) in der Mathemtik ist es üblich N als Synonym für eine Natürlich Zahl zu betrachten, so wie R für rationelle Zahlen etc.pp. 7.) Sonderfall 1 ist zu wenig und berücksicht eben nicht negative Zahlen 8.) die Berechnung in for X := 0 to Trunc(Sqrt(n)) ist zwar auf Grund des Delphi Compilers möglich sollte aber aus Sicht eines Standard PASCAL Codes vermieden werden. Unter Umständen, bei erweiterte PASCAL Dialekten mit einer for i to x step y Syntax ist nämlich x als Schleifenendebedingung dynamisch veränderbar. 9.) wenn es geht sollte man immer auf unnötige Sprachkonstruke verzichten und statt dessen mit "mathematischen" Zuweisungen arbeiten. 10.) wenn es geht exit/goto/continue vermeinden 11.) man muß nur mit ungeraden Zahlen die Trialdivision durchführen. Da es aber in Delphi keine for i tox step y Schleife gibt müsste man sich behelfen mit for x := 2 to Trunc(Sqrt(N)) div 2 do und mit if N mod (i*2+1) = 0 arrbeiten, um eben den offensichtlichen mathematischen Erfordernissen gerecht zu werden. Es geht hier um Exaktheit in der Programmier Arbeit die man leistet. Allerdings ist eine solche Zähleschleife wesentlich schlechter zu verstehen als eine while Schleife. In deinem Falle testet deine Funktion die Zahl N doppelt so häufig als es nötig wäre, ergo Effizienzeinbußen.
Delphi-Quellcode:
function IsPrime(const N: Int64): Boolean; var Root,Candidate: Int64; begin Result := Odd(N) and (N > 2); // Eine Primzahl ist ungerade und größer 1, ausser der 2 if Result then begin // da wir N als Int64 vorgegeben haben können wir NICHT per Zählschleifen arbeiten, Delphi unterstützt // keine Int64 als Schleifenzähler, ergo while schleife Root := Trunc(Sqrt(N)); Candidate := 3; while Result and (Candidate < Root) do begin Result := N mod Candidate <> 0; // statt IF THEN eine mathematische, boolsche Zuweisung Candidate := Candidate + 2; end; end else Result := N = 2; // den einzigsten Fall einer geraden Primzahl berücksichtigen // statt IF THEN eine boolsche Zuweisung end; |
Re: guter stil????
Es muss
Delphi-Quellcode:
statt
while Result and (Candidate <= Root) do
Delphi-Quellcode:
heißen, da ja schon mit Trunc abgerundet wurde.
while Result and (Candidate < Root) do
[edit]In deiner ersten Funktion ist es noch richtig, da fehlt dafür ein Semikolon :zwinker: . [/edit] |
Re: guter stil????
Delphi-Quellcode:
while x > 0 do
if x < 5 then inc(x) else dec(x); sowas ist ebenfalls schlecht, das es nicht mehr grafisch von link nach rechts erfassbar ist. Man muß also immer ganz genau lesen damit man weis was passiert.
Delphi-Quellcode:
das wäre Standard konform, ist aber ziemlich aufgebläht, also hat man auch im Standard Vereinfachungen der Schreibweise berücksichtigt. ABER das dann grafisch konform mit "virtuellen" Einrückungen a 2 Zeichen.while x > 0 do begin if x < 5 then begin Inc(x); end else begin Dec(X); end; end;
Delphi-Quellcode:
Man hat also das begin end aus dem while Sourceblock entfernt, aber ALLES nach dem while ist weiterhin 2 Zeichen grafisch eingerückt. Jeder PASCAL Bezeichner ist steht dabei am Anfang dieser Einrückung, nicht irgendwo.
while x > 0 do
if x < 5 then begin Inc(x); end else begin Dec(x); end; Nun entfernen wie die unnötigen begin end blöcke
Delphi-Quellcode:
Das sieht schonmal sehr gut aus. Alles ist noch in 2'er Einrückungen Anweisung für Anweisung an ihrer grafischen Position links stehend.
while x > 0 do
if x < 5 then Inc(x); else Dec(x); Abfragen wie IF THEN ELSE wurden weiter vereinfacht indem die Regel hinzukam das man deren Anweisungen auf gleiche Zeile hochziehen kann. Die betrifft auch das else. Dabei ist aber zu beachten das man alles hochzieht.
Delphi-Quellcode:
Der else Zweig sollte nun ebenfalls 2 Zeichen eingerück werden da er defakto ja ein eigener Sourceblock darstellt und ohne die Einrückung der if then Sourceblock damit grafisch verschmelzen würde.
while x > 0 do
if x < 5 then Inc(x) else Dec(x); Wichtig ist einfach: - man liest von Link nach Rechts - eine 2 Zeichen Einrückung markiert grafisch einen Sourceblock, sprich einen lokalen Gültigkeitsbereich, oder eine Programmverzweigungsblock. - am Anfang dieser Einrückungen steht der PASCAL Sprachbezeichner und danach das was passiern soll, also immer LINKS->RECHTS.
Delphi-Quellcode:
Man sieht sehr deutlich die sich grafisch ergebende Hierarchie der Abarbeitung im Programmfluß.// Links Rechts while -> x > 0 if -> x < 5 -> inc(x) else -> dec(x) Gruß Hagen |
Re: guter stil????
Das Auseinanderreißen von Sparchkostrukten ist ebenfalls schlechter Stil, also sowas:
Delphi-Quellcode:
Bei all diesen Konstrukten gehört alles in eine Zeile, also so
if x > 0
then while x > 0 do repeat until x > 0;
Delphi-Quellcode:
Das ist ganz einfach begründet, denn die EINFACHSTE Programmverzweigung, nämlich keine, wird durch ein BEGIN markiert.while Bedingung do if Bedingung then repeat until Bedingung;
Delphi-Quellcode:
Die bedingten Programmverzweigungen ersetzen nun einfach dieses begin
function XYZ(): Result;
begin // <- begin // <- separater Programblock ABC; end; end;
Delphi-Quellcode:
Gruß Hagen
function XYZ(): Result;
begin // <- // be- -gin if Bedingung then // <- separater Programblock ABC; // be- -gin while Bedinung do ABC repeat ABC; until Bedingung; // logisch betrachtet einfach mal umdrehen und so betrachten until Bedingung ABC; repeat end; |
Re: guter stil????
Hi Hagen,
Zitat:
Zitat:
Zitat:
Zitat:
Zitat:
Zitat:
Zitat:
Zitat:
Zitat:
Zitat:
Zitat:
Ich hab' meinen Source verbessert (war übrigens auf Grund von zwei Tippfehlern vorher nicht lauffähig):
Delphi-Quellcode:
cu
function IstPrim(const n:integer):boolean;
var x:integer; begin // Sonderfälle beachten if (n <= 1) then begin result:=false; exit; end; result:=true; for x:=2 to Trunc(Sqrt(N)) do if ((n mod x) = 0) then begin result:=false; exit; end; end; // eine meiner Lieblingsfunktionen ;) // bildet das (<condition>?<true>:<false>)-Konstrukt aus C/PHP nach function iif(const Condition:boolean; const IfTrue,IfFalse:string):string; begin if (Condition) then result:=IfTrue else result:=IfFalse; end; // integer: siehe oben procedure Zerlegen(var OutputLabel:TLabel; const n:integer); var x:integer; begin x:=2; while ((n mod x) <> 0) do Inc(x); // Korrektur: OK, so schwachsinnig war sie doch nicht. Hab' mich verlesen. OutputLabel.Caption:=OutputLabel.Caption+iif(length(OutputLabel.Caption) > 0,'*','')+IntToStr(x); if (not IstPrim(n div x)) then Zerlegen(OutputLabel,n div x); m:=m*x; end; procedure TForm1.Button1Click(Sender: TObject); begin m:=1; label2.Caption:=''; if (IstPrim(strtoint(edit1.Text))) then Label2.Caption:=edit1.Text+' ist eine Primzahl!' else begin Zerlegen(Label2, StrToInt(Edit1.Text)); Label2.Caption:=Label2.Caption+'*'+IntToStr(StrToInt(Edit1.Text) div m); end; end; |
Re: guter stil????
Zuviel rede ich eh nicht mit, da ich ja sowieso meinen eigenen "guten" Programierstil hab :roll:
Aber zu dem ELSE, meiner Meinung nach hat das die selbe Wertigkeit wie das IF und wird demnach nicht eingerückt.
Delphi-Quellcode:
Das BEGIN ziehe ich mit auf die Zeile mit der Bedingung/Schleife ... daß die nachfolgenden Codezeilen zu der Bedingung/Schleife gehöen sehe ich ja an der Einrückung ^^
If ... Then ...
Else ...; // bei kurzen Blöcken auch mal If ... Then ... Else ...; If ... Then Begin ...; End Else ...; If ... Then Begin ...; End Else Begin ...; End; If ... Then Begin ...; End Else If ... Then Begin ...; End Else Begin ...; End;
Delphi-Quellcode:
Und irgendwie finde ich meine Version übersichtlicher, als eure ._.
If ... Then Begin
...; ...; ...; End; If ... Then ...; ...; ...; If ... Then ...; ...; ...;
Delphi-Quellcode:
Und ja, ich mache manchmal immernoch mehrere Befehle in eine Zeile, wenn es logisch zusammengehört und so auch noch übersichtlicher ist :tongue:
// MEINE
If ... Then Begin ...; End Else If ... Then Begin ...; End Else Begin ...; End; // das Andere If ... Then Begin ...; End Else If ... Then Begin ...; End Else Begin ...; End; [add] zu der einen Funktion ... wie siht das für dich aus?
Delphi-Quellcode:
function IstPrim(const n: integer): boolean;
var i: integer; begin result := false; if n <= 1 then exit; // Sonderfälle beachten for i := 2 to Trunc(Sqrt(N)) do if n mod i = 0 then exit; result := true; end; |
Re: guter stil????
Delphi-Quellcode:
:stupid:
// A) IF - Kurtzschreibweise
if ... then ...; // B) IF - Kurtzschreibweise mit Elsezweig if ... then ... else ...; // C) IF - Kurtzschreibweise mit Elsezweig in neuer Zeile if .......... then ........ else .......... ; // D) IF - Schreibweise mit Elsezweig if .................... then ....................; else .................... // D) IF - BlockSchreibweise if .................... then begin ....................; .................... end; // E) IF - BlockSchreibweise und Else-Zweig if .................... then begin ....................; .................... end else begin ....................; .................... end; // oder: if .................... then begin ....................; .................... end else begin ....................; .................... end; // auch ne Art, kann aber in der VCL lang wedern ;-) if ...... then ...... else if ...... then ...... else if ...... then ...... else .....; // kann ich nich leiden ;-) // 1. if .................... then begin ....................; .................... end else begin ....................; .................... end; // 2. ( unübersichtlich ) if ... then ... else ... |
Re: guter stil????
Also, ich denke solange sich der Programmierer bei seinen Einrückungen was gedacht hat und vor allem den Stil konsistent durchzieht (!!) macht es nicht so den großen Unterschied ob er jetzt
Delphi-Quellcode:
oder
if ... then begin
end else begin end;
Delphi-Quellcode:
oder noch irgendwas anderes schreibt. Ist auch zu einem gut Teil Geschmackssache. Nur durcheinander würfeln sollte man das nicht.
if ... then
begin end else begin end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:46 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 by Thomas Breitkreuz