Über den Kodierungsstil - Seite 3

 

Ich ziehe es vor, die Funktionen in separate Aktionen aufzuteilen, so dass der Code eine klare Struktur hat... das ist einfacher zu optimieren...

 
Mathemat >> :

Im Grunde handelt es sich um normalen Code, der die gleichen Berechnungen durchführt wie die verschachtelte if-Konstruktion. Aber irgendwo habe ich gehört, dass die Rückgabe in der Funktion eine sein sollte. Wahrscheinlich tut man das, um nicht mit ihnen in Konflikt zu geraten. Ich halte mich nicht strikt an diese Regel.

Ansonsten ist mein Ansatz dem Ihren sehr ähnlich, C-4, bis auf ein paar Details.


Ja, eine solche Meinung gibt es. Der Return-Operator ist jedoch nicht dasselbe wie GOTO. In der Praxis bin ich noch nie auf unerwartete Rückwürfe gestoßen. Im Gegenteil, das Programm wird lesbarer und strukturierter, wenn solche Operatoren und Bedingungen verwendet werden (alle Prüfungen laufen nacheinander von oben nach unten und bilden eine Art Spalte). Außerdem garantiert der Operator return im Gegensatz zu if() das Verlassen der Funktion, und genau das wird in den meisten Fällen benötigt, denn es hat keinen Sinn, Daten weiter auszuwerten, wenn eine Bedingung nicht erfüllt ist.

 

Die letzte Regel hat mir besonders gut gefallen: "Niemals die Operation 'Kopieren und Einfügen' verwenden". Aber leider kann ich das nicht nachvollziehen. Wie ist es möglich, den IDE-Editor zu verwenden und nicht "Copy&Paste" zu benutzen, was viel Zeit spart?

Wie sich herausstellt, ist das nicht der Fall: Ich stelle fest, dass ich gerade deshalb oft logische Fehler finde, die schwer zu erkennen sind.

P.S. Die Forum-Engine erlaubt es mir nicht, dieses Fragment aus meinem ersten Beitrag zu formatieren

// open
// .pairsToOpen
// .combineAndVerify( )
// Собирает из двух валют символ и выполняет все проверки, нужные для его открытия.
// Возвращает валидность пары для открытия.
// Последний аргумент - [...]
bool
combineAndVerify( string quoted, string base, double& fp1 )

Genau so ist es bei mir: Die ersten drei Zeilen sehen anders aus, strukturierter. OK, auf Biegen und Brechen:


Wie ich kommentiere funktioniert

 

Hier sind noch ein paar weitere Regeln, die mir in letzter Zeit in den Sinn gekommen sind und die ich in meinem eigenen Haus bereits umgesetzt habe:


1. Globale Variablen (GV) werden nicht alle am Anfang des Codes deklariert, sondern je nach Bedarf vor den entsprechenden Funktionen, die sie verwenden.

2. Vor jeder Funktion wird auch beschrieben, welche GPs sie verwendet (Eingabe) und welche sie verändert (Ausgabe), wenn sie tatsächlich aufgerufen wird. Und nach der Funktion können Sie auch erklären, welche Allgemeinmediziner nicht mehr eingesetzt werden sollen.

3. All diese Kommentare, zusammen mit leeren Trennlinien zwischen den Funktionen und der Einschränkung "Funktionslänge nicht mehr als 20 Zeilen" erhöhen die Größe der Codedatei um das 1,5-2-fache. Das macht es nicht schwieriger zu kompilieren, und wir haben kein Papier dafür übrig.

4. Wozu sind Hausärzte nützlich? Angenommen, wir berechnen eine Variable eines komplexen Typs in der Funktion foo( ..., <Typ>& Variable ) und übergeben sie per Referenz. Wenn wir diese Variable dann wiederholt in verschiedenen Codefragmenten verwenden, müssen wir jedes Mal die Funktion foo( ) aufrufen. Es scheint in Ordnung zu sein - abgesehen davon, dass wir jedes Mal Zeit für die Auswertung dieser Variable aufwenden, fügen wir auch ein paar Zeilen (für die Variablendeklaration und den Funktionsaufruf) in jede Funktion ein, die die Variable verwendet. Warum? Wenn dies eine so genannte Code-Wiederverwendung ist, ist sie irgendwie suboptimal: Abgesehen davon, dass die Funktion foo( ) zu häufig verwendet wird, brechen wir auch die Struktur der Funktionsaufrufe, indem wir die Funktion foo( ) des Benutzers "aus den Kategorien herausnehmen" und ihre Aufrufe nicht hierarchisch sind. Es ist einfacher, eine Variable als "kategoriefremde" Variable zu deklarieren, d.h. als global.

Ich persönlich würde strikt hierarchische Funktionen einer solch fragwürdigen Wiederverwendung von Code vorziehen. Ich habe bereits über die Hierarchie gesagt: Jede Funktion der n-ten Ordnung wird nur von einer Funktion der (n-1)-ten Ordnung und nur von "ihrer" Funktion aufgerufen. Siehe mein Beispiel zur Erläuterung der Funktionshierarchie im Bild mit grünem Hintergrund oben.

5. Aber natürlich ist der Code nicht immer optimal im Sinne der Hierarchie, und manchmal muss man "fremde" Funktionen aufrufen. In diesem Fall können Sie ihren Platz in der Funktionshierarchie in Klammern /* */ vor den Namen der "fremden" Funktion schreiben.


Vielleicht ist das alles albern und übertrieben, aber ich weiß sehr wohl, dass ich einen Code schreibe, den ich wahrscheinlich mehr als einmal bearbeiten muss. Hier denke ich, dass es besser ist, sich in Kommentaren und Strukturen zu beruhigen.

 
Vinin >> :
Über die Größe der Funktion. Ich versuche, die Funktion auf einen Bildschirm zu bringen. Damit Sie das Ganze sehen können.

Ich versuche, den Code so zu schreiben, dass der Quellcode in Blöcken korrigiert werden kann, und dass es bequem ist, etwas hinzuzufügen oder zu ändern

Kommentare sollten nicht weniger als 30% des Codes ausmachen

(das lernte ich in den 80er Jahren, als ich mir den Quellcode von UNIX-Betriebssystemen ansah, RT11)

Ein halbes Jahr später ist der Code vergessen - wenn Sie ihn korrigieren müssen, geben Ihnen die Kommentare einen schnellen Überblick über das Thema!

(Ich habe eine reale Erfahrung an einem Produktionsstandort gemacht, als ich nach 5 Jahren meinen eigenen Code gelesen habe)

dank der Kommentare habe ich mir alles an einem Tag gemerkt und am Abend Änderungen vorgenommen)

Ich versuche, den Code so auszurichten, dass er lesbar ist, und nicht an Leerzeichen und Einrückungen zu sparen.

Vergleichen Sie die beiden Beispiele! Welcher Code liest sich besser?


1)

extern string gslM001rus="Все что касается индикации" ;
// 
extern bool gpInfoParameter =false ; // выводить параметры
extern bool gpInfoLevel =true ; // выводить параметры
extern bool _gDeleteObjectGrafic =0 ; // 1-Удалять объекты на графике при завершении 0-не удалять
extern double FlatSBuy =0.0010 ; // =0.00050; // пипов на пробой ТОЛЬКО ДЛЯ ИНДИКАТОРА!!!
extern double FlatSSell =0.0010 ; // =0.00050; // пипов на пробой ТОЛЬКО ДЛЯ ИНДИКАТОРА!!!
extern int DayHistory =50 ; // Сколько дней в истории показывать
// флет азии 
extern int iTimeEndFlatAsiaHour = 5 ; // Конец утреннего флета
extern int iTimeEndFlatAsiaMin = 15 ; // Конец утреннего флета
// Время длины флета измеряется минутами от окончания и назад
// 360 минут эт о6 часов назад от 5:15 получаем 23:15 вчерашнего дня
extern int iTimeEndFlatAsiaSizeMin = 360 ; // + количество минут  флета// 
extern string sTimeBreakFlatAsia ="20:00:00" ; // Время до которого разумно ждать пробой и выставление ордеров
extern int pУровниHighLowDAY =1 ; // выводить уровни HIGH LOW
extern color ЦветПятницыHIGH =DeepSkyBlue ;
extern color ЦветПятницыLOW =DeepSkyBlue ;
extern color ЦветHIGHDAY =DarkViolet ;
extern color ЦветLOWDAY =DarkViolet ;
extern color lColorFAH =OrangeRed ;
extern color lColorFAL =SandyBrown ;
extern color lColorSignalSELL =Red ;
extern color lColorSignalBUY =Red ;

 


2)


extern string gslM001rus="Все что касается индикации"      ;
//                                                                  
extern bool   gpInfoParameter         =false               ; // выводить параметры
extern bool   gpInfoLevel             =true                ; // выводить параметры
extern bool   _gDeleteObjectGrafic    =0                   ; // 1-Удалять объекты на графике при завершении 0-не удалять
//                                                            
extern double FlatSBuy                =0.0010              ; // =0.00050;  // пипов на пробой ТОЛЬКО ДЛЯ ИНДИКАТОРА!!!
extern double FlatSSell               =0.0010              ; // =0.00050;  // пипов на пробой ТОЛЬКО ДЛЯ ИНДИКАТОРА!!!
extern int    DayHistory              =50                  ; // Сколько дней в истории показывать

//                                                         
// флет азии                                               
//                                                         
extern int    iTimeEndFlatAsiaHour    = 5                  ; // Конец утреннего флета
extern int    iTimeEndFlatAsiaMin     = 15                 ; // Конец утреннего флета
// 
// Время длины флета измеряется минутами от окончания  и назад
//   360 минут эт о6 часов назад от 5:15 получаем 23:15 вчерашнего дня
//
extern int    iTimeEndFlatAsiaSizeMin = 360                ; // + количество минут  флета
//                                                            
//                                                              
//                                                            
extern string sTimeBreakFlatAsia      ="20:00:00"          ; // Время до которого разумно ждать пробой и выставление ордеров
//                                                         
extern int    pУровниHighLowDAY       =1                   ; // выводить уровни HIGH LOW
//
extern color  ЦветПятницыHIGH         =DeepSkyBlue         ;
extern color  ЦветПятницыLOW          =DeepSkyBlue         ;
extern color  ЦветHIGHDAY             =DarkViolet          ;
extern color  ЦветLOWDAY              =DarkViolet          ;
extern color  lColorFAH               =OrangeRed           ;
extern color  lColorFAL               =SandyBrown          ;
extern color  lColorSignalSELL        =Red                 ;
extern color  lColorSignalBUY         =Red                 ;
//
//
 
                                                    
 
Mathemat >> :

if(param1!=1)return;

if(param2!=2)return;

...

if(param5!=5)return;

Print("Наконец-то дошли!");

Im Grunde handelt es sich um normalen Code, der die gleichen Berechnungen durchführt wie die verschachtelte if-Konstruktion. Aber irgendwo habe ich gehört, dass die Rückgabe in der Funktion eine sein sollte. Wahrscheinlich tut man das, um nicht mit ihnen in Konflikt zu geraten. Ich halte mich nicht strikt an diese Regel.

Im Übrigen ist mein Ansatz dem Ihren sehr ähnlich, abgesehen von ein paar Details.

Ich ziehe es vor, auch alleine auszugehen!

leichter zu kontrollieren


Wenn Sie einen Wert zurückgeben wollen, dann


anstelle von

wenn ( a > c )

zurück ( 3 );

wenn ( l < b )

zurück (5);

...

...

wenn ( h != b )

zurück (100);

---

lieber


wenn ( a > c )

codret = 3;

wenn ( l < b )

codret = 5;

...

...

wenn ( h != b )

codret = 100;


// insbesondere, wenn vor der Rückgabe einige zusätzliche Operationen durchgeführt werden, die für alle Ausgänge gleich sind

... zum Beispiel hier machen wir etwas anderes

retrun( codret);

}


 

ein kleiner Kommentar...

Um Texte in Blöcke zu unterteilen, verwende ich eine Zeichenzeile mit dem Code U0151. Für diejenigen, die es nicht wissen: Es wird so geschrieben:

  1. Alt gedrückt halten
  2. drücken Sie auf der numerischen Tastatur nacheinander die Ziffern des Symbolcodes 0, dann 1, dann 5, dann 1
  3. Freigabe Alt

für "richtige" Schriftarten erhalten wir ein Minuszeichen, aber ohne "Leerzeichen" an den Enden. dann kopieren Sie es so oft wie nötig eine durchgezogene Linie, die als gute visuelle Grenze dient...

// обычная линия
// -----------------------------------------------------------------------------------

// сплошная линия
// —————————————————————————————————

// —————————————————————————————————
// Вот такие часто делаю ЗАГОЛОВКИ
// —————————————————————————————————

 

auch eine clevere Trennlinie für den Kommentartextblock - er sieht vollkommen symmetrisch aus, aber es gibt eine erste öffnende und eine zweite schließende Zeile:


/*///—————————————————————————————————————————
это

mehrzeiliger Kommentarblock
...................

/*///-----------------------------------------

 

Yura, dein Beispiel mit einer Rückgabe ist natürlich logisch. Beachten Sie jedoch, dass in diesem Fall alle ifs immer ausgeführt werden, im Gegensatz zu dem Fall mit vielen Rückgaben, bei dem der Ausgang der Funktion unmittelbar nach Erreichen der Zeichenkette mit der Bedingung erfolgt.

ForexTools, vielen Dank, ich habe Ihre Design-Ideen aufgegriffen.