À propos du style de codage - page 3

 

Je préfère séparer les fonctions en actions distinctes, afin que le code ait une structure claire... c'est plus facile à optimiser...

 
Mathemat >> :

En fait, il s'agit d'un code normal qui effectue les mêmes calculs que la construction if imbriquée. Mais j'ai entendu dire quelque part que le retour dans la fonction devait être un. Probablement, c'est fait pour ne pas être mêlé à eux. Je ne suis pas strictement cette règle.

À d'autres égards, mon approche est très proche de la vôtre, C-4, à quelques détails près.


Oui, cette opinion existe. Mais l'opérateur de retour n'est pas la même chose que GOTO. Dans la pratique, je n'ai jamais rencontré de jet de retour inattendu. Au contraire, le programme devient plus lisible et plus texturé lorsque de tels opérateurs et conditions sont utilisés (tous les contrôles vont un par un de haut en bas en formant une sorte de colonne). En outre, contrairement à l'opérateur if(), return garantit la sortie de la fonction, et c'est exactement ce dont on a besoin dans la plupart des cas, car il est inutile d'évaluer les données plus avant si certaines conditions ne sont pas remplies.

 

J'ai beaucoup aimé la dernière règle : "Ne jamais utiliser l'opération 'copier-coller'". Mais, hélas, je ne le suis pas. Comment est-il possible d'utiliser l'éditeur de l'IDE et de ne pas utiliser le "copier/coller" qui permet de gagner beaucoup de temps ?

Il s'avère que non, ce n'est pas le cas : je remarque que c'est à cause de cela que je trouve souvent des erreurs logiques, qui sont difficiles à attraper.

P.S. Le moteur du forum ne me permet pas de formater ce fragment de mon premier message

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

Exactement comme chez moi : les trois premières lignes sont différentes, plus structurées. OK, par la manière forte ou la manière faible :


Comment je commente les fonctions

 

Voici quelques règles supplémentaires qui me sont venues à l'esprit récemment et que j'ai déjà mises en œuvre chez moi :


1. Les variables globales (VG) ne sont pas déclarées toutes au début du code, mais selon les besoins, avant les fonctions correspondantes qui les utilisent.

2. Avant chaque fonction, nous décrivons également les PG qu'elle utilise (entrée) et ceux qu'elle modifie (sortie) lorsqu'elle est effectivement appelée. Et après la fonction, vous pouvez également expliquer quels sont les médecins généralistes qui ne seront plus utilisés.

3. Tous ces commentaires, ainsi que les lignes de séparation vides entre les fonctions et la limitation "longueur de la fonction pas plus de 20 lignes" augmentent la taille du fichier de code de 1,5 à 2 fois. Cela ne le rend pas plus difficile à compiler, et nous n'avons pas de papier à gaspiller pour cela.

4. À quoi servent les médecins généralistes ? Supposons que nous calculions une variable d'un type complexe dans la fonction foo( ..., <type>& variable ), en la passant par référence. Ensuite, si nous utilisons cette variable à plusieurs reprises dans différents fragments de code, nous devrons appeler la fonction foo( ) à chaque fois. Cela semble correct - en plus de passer du temps à chaque fois pour l'évaluation de cette variable, nous ajoutons également quelques lignes (pour la déclaration de la variable et l'appel de la fonction) dans chaque fonction utilisant la variable. Pourquoi ? Si c'est ce qu'on appelle la réutilisation du code, c'est en quelque sorte sous-optimal : outre le fait que la fonction foo( ) est trop souvent utilisée, nous brisons également la structure des appels de fonction, en rendant la fonction foo( ) "hors catégorie" et ses appels non hiérarchisés. Il est plus facile de déclarer une variable comme une variable "hors catégorie", c'est-à-dire globale.

Personnellement, je préférerais des fonctions hiérarchiques strictes à une réutilisation aussi discutable du code. J'ai déjà dit à propos de la hiérarchie : chaque fonction d'ordre n n'est appelée que par une fonction d'ordre (n-1) et seulement "sa" fonction. Voir mon exemple expliquant la hiérarchie des fonctions dans l'image à fond vert ci-dessus.

5. Mais bien sûr, le code n'est pas toujours optimal au sens de la hiérarchie, et il faut parfois appeler des fonctions "étrangères". Dans ce cas, vous pouvez écrire sa place dans la hiérarchie des fonctions entre parenthèses /* */ avant le nom de la fonction "alien".


Tout cela est peut-être stupide et excessif, mais je sais très bien que j'écris du code que je devrai probablement modifier plus d'une fois. Ici, je pense qu'il est préférable de se rassurer en commentant et en structurant.

 
Vinin >> :
Sur la taille de la fonction. J'essaie de faire en sorte que la fonction tienne sur un seul écran. Pour que vous puissiez voir l'ensemble.

J'essaie d'écrire du code de sorte que le code source puisse être corrigé par blocs, et qu'il soit pratique d'ajouter et de modifier

les commentaires ne doivent pas représenter moins de 30 % de la taille du code

( appris à faire cela dans les 80x, en regardant le code source des systèmes d'exploitation UNIX, RT11)

une demi-année plus tard, le code est oublié - si vous devez le corriger, les commentaires vous permettent de comprendre rapidement le sujet !

(J'ai eu une expérience réelle sur un site de production lorsque je lisais mon propre code après 5 ans).

grâce aux commentaires, je me suis souvenu de tout en un jour et j'ai fait les changements le soir même)

J'essaie d'aligner le code pour qu'il soit lisible, sans lésiner sur les espaces et les retraits.

comparez les deux exemples ! quel code se lit le mieux ?


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("Наконец-то дошли!");

En fait, il s'agit d'un code normal qui effectue les mêmes calculs que la construction if imbriquée. Mais j'ai entendu dire quelque part que le retour dans la fonction devait être un. Probablement, c'est fait pour éviter de s'y mêler. Je ne suis pas strictement cette règle.

Pour le reste, mon approche est très proche de la vôtre, à quelques détails près.

Je préfère la même façon de sortir seul !

plus facile à contrôler


Si vous voulez retourner une valeur, alors


au lieu de

si ( a > c )

retour ( 3 ) ;

si ( l < b )

retour (5) ;

...

...

si ( h != b )

retour (100) ;

---

préférez


si ( a > c )

codret = 3 ;

si ( l < b )

codret = 5 ;

...

...

si ( h != b )

codret = 100 ;


// surtout si certaines opérations supplémentaires communes à toutes les sorties sont effectuées avant le retour.

... par exemple ici nous faisons autre chose

retransmission( codret) ;

}


 

un petit peu de commentaire...

Pour diviser les textes en blocs, j'utilise une ligne de caractères avec le code U0151. Pour ceux qui ne le savent pas, ça se tape comme ça :

  1. maintenez la touche Alt enfoncée
  2. sur le clavier numérique, appuyez successivement sur les chiffres du code du symbole 0 puis 1 puis 5 puis 1
  3. libérer Alt

pour les polices "correctes", on obtient un signe moins mais sans "espace" aux extrémités. ensuite, on le copie autant de fois que nécessaire pour obtenir une ligne pleine qui sert de bonne bordure visuelle...

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

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

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

 

également une ligne de découpage astucieuse pour le bloc de texte du commentaire - il semble parfaitement symétrique, mais il y a une première ligne d'ouverture et une deuxième ligne de fermeture :


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

bloc de commentaires multilignes
...................

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

 

Yura, votre exemple avec un seul retour, bien sûr, est logique. Mais attention, dans ce cas, tous les ifs sont toujours exécutés, contrairement au cas avec de nombreux return, où la sortie de la fonction est obtenue immédiatement après avoir atteint la chaîne avec la condition.

ForexTools, merci, j'ai pris en compte vos idées de conception.