bonjour,
Suite à la remontée d'un post concernant l'optimisation du code, et étant dans une phase où j'arrive à atteindre mes objectifs (raisonnables quand-même ) je me retrouve à essayer de réviser mes précédents programmes pour qu'ils soient au maximum ecrits dans les règles de l'art.
J'arrive sans (trop) de problème à faire en sorte que mes fonctions de base soient suffisament courtes pour qu'elle tiennent à l'écran mais par contre, la fonction qui, elle, gère les appels de ces fonctions est toujours assez imposante.
Dans le post cité plus haut, on m'a gentilment proposé le bûcher (je veux des cendres) lorsque j'ai écrit qu'il était assez difficile de respecter la règle des 50 lignes (ou 40 ou 80 selon...mais on s'est bien compris) lorsque l'on avait ce genre de code :
switch (lettre)
{
case 'a':
faire ceci;
break;
case 'b':
faire cela;
break;
etc...;
}
"surtout si tu vas jusqu'à z".
Du coup je me suis posé la question de comment éviter ce genre de truc si par exemple j'attribue une fonction différente à chaque touche du clavier.
Ca dépend, qu'est-ce que tu comptes mettre dans tes cases ?
Si c'est juste un appel de fonction, essaye d'avoir toujours le même prototype et crée une table de correspondance entre lettre<->fonction. Ca donnerai genre un truc :
struct {
char c;
int (*f)(int, int); /* Tu mets ce que tu veux, j'ai mis ça au pif)
} tab = {
{ 'a', fonctionA },
{ 'b', fonctionB },
...
};
Dans ce cas là autant utilisé un tableau de pointeurs sur fonction, et on appelle la fonction comme ça non: tab[lettre-'a']()?
Mais bon c'est vachement contraignant d'avoir le même prototype pour chaque fonction.
Citation
Dans le post cité plus haut, on m'a gentilment proposé le bûcher (je veux des cendres) lorsque j'ai écrit qu'il était assez difficile de respecter la règle des 50 lignes (ou 40 ou 80 selon...mais on s'est bien compris) lorsque l'on avait ce genre de code :
Si pour chaque cas tu appelles une fonction différente, je vois pas ce qu'on pourrait faire de mieux qu'un switch.
Si pour chaque cas tu appelles une fonction différente, je vois pas ce qu'on pourrait faire de mieux qu'un switch.
Le tableau de pointeur de fonction me semble très bien, dans ce cas, non?
Citation : Twistted destiny
Mais bon c'est vachement contraignant d'avoir le même prototype pour chaque fonction.
Souvent on manipule les mêmes données dans les branches d'un même switch, donc le problème n'est pas insurmontable.
Ce sera surement plus lisible qu'un switch avec une dizaine de branchements, je pense.
Citation : Drx
Dans le post cité plus haut, on m'a gentilment proposé le bûcher (je veux des cendres) lorsque j'ai écrit qu'il était assez difficile de respecter la règle des 50 lignes
Dans ce cas là autant utilisé un tableau de pointeurs sur fonction, et on appelle la fonction comme ça non: tab[lettre-'a']()?
Pas forcément, parce que déjà tu n'es pas sûr que tous les caractères se suivent (bon, ok, je pense qu'on aura pas ce souci) et s'il veut rajouter d'autres valeurs pour son switch, il pourra.
Et faire un tableau, ça ne rend pas le code plus facile à maintenir (même si ça n’est pas plus difficile non plus), or c’est ça le but de ce genre de règles.
En général, je n’aime pas trop les règles sur le nombre de lignes dans une fonction. J’ai l’impression que ça tend plutôt à forcer à écrire du code stupide pour respecter la règle qu’à forcer à découper de manière plus intelligente les fonction. Si tu as besoin d’une fonction qui, par exemple, convertit les codes de touche de la bibliothèque du système vers des codes identiques pour toutes les plateformes (ce que font les bibiliothèque comme la SDL), utiliser un gros switch avec juste des caseSYS_FOO: returnSDL_FOO; est tout à fait légitime (bon, c’est pas comme ça qui fait la SDL, mais il y a des switchs avec du code plus compliqué pour chaque type d’événement, ce qu’on pourrait considérer comme pire… et ça fait plus que 50 lignes ).
Par contre, je me fixe une limite sur le nombre de caractères par ligne (en tout cas en général ; difficile de rester à 80 colonnes quand le nom d’une méthode est déjà plus long…).
salut,
merci pour les infos, mais en fait les notions dont vous me parlez m'échappent pour le moment, je vais allez potasser le tuto de uknow sur les pointeurs de fonctions pour voir si je m'en sort avec ça.
Bon, après je dis fonction, mais ça pourrait être une fonction pour a et une addition pour b...et parfois des tests supplémentaires.
Citation : GurneyH
Citation : drx
Dans le post cité plus haut, on m'a gentilment proposé le bûcher (je veux des cendres) lorsque j'ai écrit qu'il était assez difficile de respecter la règle des 50 lignes
C'est pour rire, hein!
Oui, je m'en doute bien, sinon je ne serais plus très frais vu qu'avant de me faire frire, je me suis déjà fais snipé (ou était-ce une grenade ?) par SofEvan puis découpé par d'autres
Toujours est-il que je vous remercie, je vais aller me remplir la tête avec (encore) une nouvelle notion...
edit : je laisse le topic ouvert jusqu'à ce que j'ai fini d'assimiler le tuto au cas où il me viendrai des questions...
En général, je n’aime pas trop les règles sur le nombre de lignes dans une fonction. J’ai l’impression que ça tend plutôt à forcer à écrire du code stupide pour respecter la règle qu’à forcer à découper de manière plus intelligente les fonction.
Le découpage que fera un débutant a toutes ses chances de ne pas être pertinent, ceci peu importe les contraintes qu'on lui a fixées .
Les bonnes habitudes c'est en apprenant qu'il faut les atteindre, après ça peut être foutu. Ils feront sans doute des découpages à la con, mais au moins ils auront les réflexes de contrôler la taille de leurs fonctions.
Pour tout dire, dans un cas d'énumération (notamment avec un switch) je me permets de déborder sur la règle de la fonction courte. Car tout simplement je considère que même si la fonction est longue, ça ne nuit pas à sa lecture. De plus si ça peut éviter de déclarer une fonction additionnelle avec comme seule justification "c'est pour que la fonction untelle ne soit pas longue" c'est, à mon gout, justifié.
Bof bof.
J'ai toujours trouvé les conseils « fonctions de moins de 50 lignes » ridicules…
Pourquoi ?
Déjà car ce sont des limites arbitraires qui varient en fonction des gens. Certains prônent pour 30 lignes, d'autres 50, d'autres 100… Et ce sans aucune justification logique. Pourquoi ces nombres en particulier ?
Les fonctions sont censés être des opérations élémentaires qui seront en général réutilisés. Découper à mort les fonctions réduisent la lisibilité et les possibilités (avec une seule valeur de retour, les possibilités sont réduites, utiliser des pointeurs quand c'est dispensable pour combler ce manque est un exemple typique du manque de lisibilité qu'une telle solution peut apporter).
Vouloir des fonctions courtes, c'est bien, mais fixer des limites très basses qu'on ne peut dépasser est contre productif. Personnellement je me repère très bien dans des fonctions de plus de 100 lignes où il faut scroller (des fonctions que je n'ai pas écrites évidemment) du temps que c'est logique est bien écrit. Mettre sous forme de petites fonctions auraient pu réduire la lisibilité (dans le cas d'un fichier un peu grand, naviguer à la recherche de ce que fait une fonction peut être très pénible).
Bref, pour moi il faut faire le plus petit possible du temps que c'est utile et que ça apporte de la lisibilité. Créer des fonctions pour créer des fonctions est ridicule à mon goût. D'ailleurs beaucoup de gros projets écrits par des mains plus expérimentés (typiquement le noyau Linux) ne respectent pas ces soient disant règles d'or…
Ah ? Bon, j’ai jamais regardé le code, mais ils demandent pourtant d’avoir au plus 24 lignes (http://www.kernel.org/doc/Documentation/CodingStyle, section 6), même si la limite n’est pas imposée aussi strictement selon la complexité du code.
EDIT: En passant, 50 ou 100 lignes ce sont presque des limites raisonnables pour la plupart des cas. Je viens de voir des gens suggérer 5 (en Ruby)
Ce ne sont que des recommandations, car pour avoir étudié pas mal de fichiers, c'est loin d'être respecté partout.
De plus, si j'ai bien lu, ils conseillent entre 1 à 2 pages de 24 lignes soit 48… Puis ce n'est pas pour ça qu'ils refusent du code de toute façon. Cela dépend de la complexité et de ce qu'il fait.
Déjà car ce sont des limites arbitraires qui varient en fonction des gens. Certains prônent pour 30 lignes, d'autres 50, d'autres 100… Et ce sans aucune justification logique. Pourquoi ces nombres en particulier ?
Les limites trouvent leur origine dans la résolution des terminaux de l'époque (80x24 caractères). Après, ce n'est qu'une adaptation aux nouvelles possibilités offertes par les interfaces graphiques
Sinon, je suis assez du même avis, essayer de faire de petites fonctions oui, mais le découpage doit rester logique.
re,
je suis ok sur le tuto de uknow, j'ai pigé le principe, pas complètement enregistré, mais j'arriverai à l'appliquer avec le tuto sous les yeux : Pas facile de trouver des moyens de l'appliquer pour se faire la main dessus.
Par contre, je n'ai pas pigé le truc sur l'index tu tableau :
Citation : Twisted Destiny
tab[lettre-'a']()
c'est une sorte de bind ?
Parce que si c'est juste pour la valeur, ça m'obligerait à faire un tableau de...120 ('z' ou presque...connais pas les valeurs par coeur) qui ne serait rempli qu'à partir de l'index 96 ('a' ou presque )
Par contre, je n'ai pas pigé le truc sur l'index tu tableau :
Citation : Twisted Destiny
tab[lettre-'a']()
c'est une sorte de bind ?
Parce que si c'est juste pour la valeur, ça m'obligerait à faire un tableau de...120 ('z' ou presque...connais pas les valeurs par coeur) qui ne serait rempli qu'à partir de l'index 96 ('a' ou presque )
un truc m'échappe ?
Justement, " lettre -'a' " permet de ne pas faire un tableau de 120 ou presque, mais seulement un tableau comportant autant de cases que de lettres de l'alphabet (si tu veux aller de a à z).
En effet, si ta lettre est 'a', donc la première : " 'a' - 'a' = 0 " ! du coup, la lettre 'a' correspond à la première case du tableau, et non à la 96 (ou presque...).
Dans l'exemple de moins1, la lettre 'c' se retrouve donc à l'indice 2, puisque c'est la troisième lettre de l'alphabet !
re,
ha ouais...mais en fait, je ne sais pas pourquoi, , je me suis imaginé un truc super complexe, en fait oui, c'est basique et ça tombe sous le sens...
Citation : uknow
ça ne doit pas être très portable tout ça.
bin déjà si ça fonctionne chez moi pour l'instant...Pis de toute façon j'aime pas les gens qui ont des Mac (<- bien évidemment je rigole là)
Si je résume, on fait des fonctions de base assez courtes tant que possible, si ça ne semble pas possible on fait en sorte que ce soit suffisamment lisible. En gros : oui, mais pas trop.
Pis de toute façon j'aime pas les gens qui ont des Mac
Aucun rapport...
Si tu prends un pc IBM, tu peux avoir des surprises, un mac non.
Fonctions sur 50 lignes max ?
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
Bonhomme !! | Jeu de plateforme : Prototype.
Bonhomme !! | Jeu de plateforme : Prototype.
Objectif Zéro Bug - le test logiciel professionnel | L'électronique de zéro | Tableaux & pointeurs | Pointeurs sur fonctions | Lecture/écriture binaire
Bonhomme !! | Jeu de plateforme : Prototype.
Objectif Zéro Bug - le test logiciel professionnel | L'électronique de zéro | Tableaux & pointeurs | Pointeurs sur fonctions | Lecture/écriture binaire
Bonhomme !! | Jeu de plateforme : Prototype.