IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

Bien quitter son programme


Sujet :

C

  1. #61
    Modérateur
    Avatar de gangsoleil
    Homme Profil pro
    Manager / Cyber Sécurité
    Inscrit en
    Mai 2004
    Messages
    10 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Manager / Cyber Sécurité

    Informations forums :
    Inscription : Mai 2004
    Messages : 10 150
    Par défaut
    Citation Envoyé par Kannagi Voir le message
    Les fonction trop haut niveau seront trop spécifique pour en faire de petite fonction
    Pas forcement, il faut savoir suffisamment decouper son code, sans pour autant faire un plat de spaghetti.

    J'ai eu la chance, ou la malchance, de travailler sur des projets de plus d'un million de lignes de code en C (je parle de vraies lignes, pas des lignes vides), et les fonctions de plus haut niveau ne sont pas les plus grandes, loin de la. Par exemple, l'un des points d'entree pour une couche reseau (serveur de socket par exemple) pourrait etre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    int main_serveur_reseau (void)
    {
      /* variables */
     
      ret_fun = init(ma_structure_reseau);
     
      if (ret_fun == SUCCESS)
      {
         ret_fun = lancer_serveur (ma_structure_reseau);
     
        if (ret_fun == SUCCESS)
        {
           while (TRUE)
           {
              boucle_reseau (ma_structure_reseau);
            }
         }
         else
         {
           /* traitement de l'erreur */
          }
       }
       else
       {
         /* traitement de l'erreur */
        }
     
       liberer_structure_reseau (ma_structure_reseau);
     
       return la_valeur_qui_va_bien;
    }
    C'est tres haut niveau, assez lisible (modulo les affinites de chacun avec ma maniere d'ecrire le code), et pourtant court.

    En repetant ce schema, tu peux avoir des fonctions le plus souvent courtes, qu'elles soient de haut niveau ou non. D'ailleurs, si tu regardes un serveur de socket, c'est souvent la partie terminale qui est longue, car une fois que tu es "au plus bas", ca ne sert plus a rien de decouper tes fonctions en sous-fonctions, voir c'est penible.
    "La route est longue, mais le chemin est libre" -- https://framasoft.org/
    Les règles du forum

  2. #62
    Expert confirmé
    Avatar de Kannagi
    Homme Profil pro
    cyber-paléontologue
    Inscrit en
    Mai 2010
    Messages
    3 219
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cyber-paléontologue

    Informations forums :
    Inscription : Mai 2010
    Messages : 3 219
    Par défaut
    Je fais une différence entre macro et define , c'est vrai que ça peut etre regroupé , mais une macro pour moi et un define possédant du code/déclaration qui peut être facilement remplacé soit par une fonction soit par inline.

    Citation Envoyé par Neckara Voir le message
    Ensuite, qu'est-ce qui est fait dans ta fonction ?
    - initialisation de la "SDL" ;
    - préparation de "décors" ;
    - boucle de jeu
    -> récupération des événements ;
    -> traitement des événements ;
    - libération des ressources ;


    En théorie, en parcourant très rapidement ta fonction, on devrait pouvoir voir le schémas ci-dessus. Ensuite, si on a besoin d'aller plus "bas-niveau", entrer dans les détails, on ira regarder le contenu de la fonction chargée d'initialiser la SDL par exemple.
    Tout cela est fait si tu lis un peu mes fonctions genre :
    Initialisation des événement : chargement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    chargement_map(&map,script);
    chargement_personnage(&hero,script,"[zack]");
    boucle du jeux:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    while(system->game == 1 || system->game == 2)
    {
           //code
    }
    Tri des evenment :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    event = MNS_Evenement();

    traitement des événement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    gameplay(event,&camera,&camcfg,&hero);

    Citation Envoyé par Neckara Voir le message
    Le code devient alors beaucoup plus explicite et lisible. Le lecteur n'a pas besoin de savoir ce que fait en détail ta fonction pour comprendre ce qu'elle fait.

    De plus, le code devient aussi bien plus maintenable.
    Les fonctions étant "indépendantes", si jamais tu change le contenu d'une fonction, tout le reste du code en sera bien moins "impacté".

    Après, c'est très facile de faire une "fonction indépendante" en mettant tout ton code dans une seule fonction... mais un projet ça peut aller très facilement à 8 000 lignes. Tu ne vas tout de même pas mettre 8 000 lignes dans une seule fonction ??

    Après oui, limiter une fonction à 15 lignes c'est ridicule mais c'est tout aussi ridicule que de faire des fonctions de 500 lignes.

    Une fonction de 300 lignes, ce n'est pas une fonction "indépendante" mais un ensemble de fonctions plus que "dépendante".
    Ah ah alors lis mon code ,déjà ce que je dis je l'ai appliqué a la lettre a mes fonction (sur mon code j'en appelle au moins une vingtaine faut lire) après si tu pense que tu peux mieux faire , je demande qu'a voir.
    Je code pas le game de manière indépendante mais ça tu débute dans le jeux vidéo tu peux pas comprendre , le game comme je l'appelle est la main principal du jeu et il n'est jamais pareil (un rpg a un shoot them up ou un jeu action) par contre on appelle souvent les même chose (chargement , événement , collision, gameplay ect que t'aurais remarqué) , mais les règle du jeu diffère donc je recode le main du jeu (appelé game ici) par rapport a ces contrainte du genre.
    Donc oui mon code est maintenable et lisible , même code qui est utilisé sur ma psp ou sur android , ou sur un jeu 2D ou 3D difficile de faire plus maintenable , lisible et multiplateforme
    Je peux te montrer des fonction plus indépendante , et plus condensé (-100 ligne) mais c'est pas le but que je veux faire passé ici.

    Pour les fonctions de moins de ligne je le redis c'est absurde je dis pas que il faut faire des fonction de plus de 200 lignes (8000 c'est trop et on peut réduire c'est évident) autant 200 me semble une limite plus que raisonnable mais ça reste une "exception" , je regarde mon code est les fonction tourne autour en général de 40~90 lignes.

    Le but c'est de pouvoir imbriqué c'est fonction et je pensais que mon code rendait bien cette philosophie (enfin c'est celui que j'avais le plus sous la main pas regardé si un autre de mes code est plus 'exemplaire').

  3. #63
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Citation Envoyé par Kannagi Voir le message
    Je fais une différence entre macro et define , c'est vrai que ça peut etre regroupé , mais une macro pour moi et un define possédant du code/déclaration qui peut être facilement remplacé soit par une fonction soit par inline.
    Non, pas dans certains cas cités plus haut comme l'utilisation d'API spécifique tout en restant portable.

    Je dois reconnaître que j'ai vite survolé le code, je n'ai pas le temps de tout lire en détails.
    Mais il est évident que tu as encore certaines choses à regrouper au seins de fonctions cohérente.


    Je code pas le game de manière indépendante mais ça tu débute dans le jeux vidéo tu peux pas comprendre
    Ne me prend pas de haut non plus s'il te plaît.

    Je ne sais pas depuis combien d'années tu travailles sur des jeux vidéos ni les diplôme que tu as, mais il ne me semble pas que tu aies une telle expérience pour me dire que "je débute et que je ne peux pas comprendre".

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    MNS_CAMERA camera;
        camera = MNS_Camera_Init((double)800/(double)600);
     
        MNS_Evenement_init();
     
        CAMERA camcfg;
        chargement_camera(&camcfg,script);
     
        MAP map;
        chargement_map(&map,script);
     
        PERSONNAGE hero;
        chargement_personnage(&hero,script,"[zack]");
        hero.angle += 90;
     
        system->sz = &hero.status;
     
        PNJ pnj;
     
        pnj.texte = 0;
        pnj.vtexte = 0;
        pnj.i = 0;
        pnj.n = -1;
        pnj.itexte = 0;
        pnj.ntexte = 0;
        pnj.rtexte = 0;
        pnj.nrtexte = 0;
        pnj.nm = map.nm;
        map.pnj = &pnj;
        hero.pnj = &pnj;
        pnj.hposition  = &hero.position;
        hero.touche = system->touche;
     
        int touche[10];
        int type = 0;
        float alpha = 1;
     
        if(system->game == 2)
        {
            hero.status = system->zack;
            hero.position = system->position;
            hero.angle = system->angle;
     
            camcfg.angle = system->camera;
        }else
        system->btime = time(NULL);
     
        float random = 0;
     
        short fullscreen = 0;
    Tout cela c'est une initialisation pour un état "initial" de ton jeu.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    MNS_Camera_Perspective(camera);
     
            event = MNS_Evenement();
            if(event.touche[27] == 1) system->game = -1;
     
            if(event.touche[GLUT_KEY_F3 + 255] == 2)  fullscreen = !fullscreen;
     
            MNS_Fenetre(800,600,fullscreen);
            MNS_Fenetre_redimension(&camera.radio);
     
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     
     
            if(type == 0)
            {
                if(event.touche[' '] == 2)
                {
                    type = 1;
     
                }
                if(system->trs == 0)
                gameplay(event,&camera,&camcfg,&hero);
            }else
            {
     
                for(i = 0;i < 10;i++)
                    touche[i] = 0;
     
                if(event.touche['w'] == 1) touche[0] = 1;
                if(event.touche['c'] == 1) touche[0] = 2;
     
                if(event.touche['s'] == 1) touche[2] = 2;
                if(event.touche['x'] == 1) touche[2] = 1;
     
                if(event.touche[system->touche[3]] == 1)   touche[1] = 1;
                if(event.touche[system->touche[4]] == 1) touche[1] = 2;
                MNS_camera_vue_sub(&camera,&camcfg.angle,0.1,touche);
     
                if(event.touche[' '] == 2)
                {
                    type = 0;
                    camcfg.angle.x = 0;
                    camcfg.angle.y = 0.75;
                    camcfg.angle.z = 2;
                }
     
            }
     
            if(system->trs == 0)
            if(event.touche[system->touche[2]] == 2)
            {
                system->trs = 2;
                Mix_PlayChannel(0, system->son[6], 0);
            }
     
     
            float hitbox = 0.12;
     
            collision_map(map,&hero.position,&hero.vitesse);
     
            system->zone = map.obj[0]->ng;
     
     
            deplacement(&hero);
     
     
            //---------------------------------
            affichage_ciel(camcfg.angle.x,camcfg.angle.y,system->ciel);
     
            affichage_map(camera,map);
     
            affichage_perso(camera,hero);
     
            game_fenetre(map,&hero,system);
     
            if(pnj.magasin == 1)
                magasin(system);
     
     
            if(system->trs == 1)
            {
                if(alpha == 1)
                gameplay(event,&camera,&camcfg,&hero);
     
                affichage_transition(alpha);
                alpha -= 0.05;
     
                if(alpha <= 0)
                {
                    alpha = 1;
                    system->trs =0;
                }
     
                hero.vitesse.x = 0;
                hero.vitesse.z = 0;
                hero.obj->n = 1;
            }
     
            if(system->trs == -1) system->trs = 0;
     
     
            if(system->trs == 2)
            {
     
                affichage_transition(1-alpha);
                alpha -= 0.05;
     
                if(alpha <= 0)
                {
                    alpha = 1;
                    system->trs =-1;
                }
     
                hero.vitesse.x = 0;
                hero.vitesse.z = 0;
                hero.obj->n = 1;
            }
     
            if(system->zone > 5)
            {
                random += fabs(hero.vitesse.x) + fabs(hero.vitesse.z);
     
                if(random > 20 && rand() % 30 == 17)
                {
                    fight(system,camera,hero);
                    random = 0;
                }
            }
     
            if(event.touche[GLUT_KEY_F2 + 255] == 1)
                fight(system,camera,hero);
     
            if(event.touche[GLUT_KEY_F4 + 255] == 2)
            {
                system->zone = 20;
                fight(system,camera,hero);
            }
     
            if(system->trs == -1)
            {
                system->camera = camcfg.angle;
     
                system->zack = hero.status;
                system->position = hero.position;
                system->angle = hero.angle;
     
                menu_game(system);
     
                hero.status = system->zack;
                hero.position = system->position;
                hero.angle = system->angle;
     
                camcfg.angle = system->camera;
            }
     
            glutSwapBuffers();
            MNS_Fps(&t,30);
     
            if(event.touche[GLUT_KEY_F1 + 255] == 2) MNS_imp_ecran("screen.bmp");
     
            //editeur_map(&map,script);
    Et là on a pelle-mêle :
    - création de la prochaine frame à afficher ;
    - affichage de la prochaine frame ;
    - récupération des événements ;
    - traitements des événements.

  4. #64
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 502
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 502
    Billets dans le blog
    1
    Par défaut
    Ne vous fatiguez pas les gars, ici, la plus grosse b***, c'est la mienne !

    "Ton code est mal indenté, regarde la ligne 22."
    "Les macros, c'est mal".
    "Les macros, c'est bien."
    "Je découpe bien mon code.
    - Non.
    - Si.
    - Non."
    "200 lignes c'est trop."
    Hé ! ho !

    Défendre une position avec des arguments valables c'est bien et vous en avez tous les 2 (et d'autres vous aident dans le débat avec aussi des arguments valables ), mais là, vous commencez à virer à la guerre de position et vous vous mettez à ne plus vouloir admettre que ce que dit l'autre n'est pas faux. Au moins en partie. Juste pour ne pas plier.

    Il n'y a pas un nombre limite de lignes à une fonction.

    Il n'y pas de "ça c'est bien", "ça c'est mal", sauf qui l'ai de manière objective. Les macros n'en font pas partie. Mais les macros ne sont pas la panacée.

    En code, il n'y a pas de vérité. Il n'y a que l'appréciation des autres pour te dire "joli code", "facile à lire ton code", "il marche bien ton code" ou encore "j'ai réussi à modifier facilement ton code".

    En fait, si, il y a une vérité : chacun d'entre nous pourra toujours apprendre et devrait toujours se demander comment il pourrait progresser, comment il aurait pu produire du meilleur code. Si vous n'y arrivez pas, vous êtes de mauvais développeurs ou vous le deviendrez tôt ou tard.

  5. #65
    Expert confirmé
    Avatar de Kannagi
    Homme Profil pro
    cyber-paléontologue
    Inscrit en
    Mai 2010
    Messages
    3 219
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cyber-paléontologue

    Informations forums :
    Inscription : Mai 2010
    Messages : 3 219
    Par défaut
    @gangsoleil
    Assez d'accord avec toi , haut niveau ne veut pas dire forcément plus long.
    Mais dans mon cas les chose bas niveau sont les codes les plus court , par exemple afficher un image ce n'est qu'un tableau en 2D donc une simple boucle avec quelque condition suffit.
    De même pour un perso en 3D c'est un ensemble de vertex donc en applique en général toutes les transformation au vertex et donc même animation squeletal et relativement courte (des boucles encore).

    Mais qu'est qu'est un personnage ? un ensemble qui interagit avec beaucoup de chose et donc pas mal appel de fonction principalement les principal chargement + affichage + free.
    sans parler de sa collision , de interaction avec la map + les interaction très spécifique.
    du coup tout ce code a un cout en ligne mais je ne le pense pas en lisibilité.
    après mon code n'est pas le plus parfait mais j'en suis plutôt satisfait sur ce qu'il fait.

    Ne me prend pas de haut non plus s'il te plaît.

    Je ne sais pas depuis combien d'années tu travailles sur des jeux vidéos ni les diplôme que tu as, mais il ne me semble pas que tu aies une telle expérience pour me dire que "je débute et que je ne peux pas comprendre".
    Disons que comme autre post était un post limite a "apprentissage de la programmation" , je m'en suis pas gênè d'en faire de même , sinon je n'ai jamais fait d'argumentation autorité.
    Mais voit tu je pense avoir une expérience que tu n'as pas et donc bon que ma fonction est pas la plus parfaite et que je peux l’amélioré j'en suis conscient ,je l'avoue volontiers et je l'ai dit même avant de avoir posté il me semble.
    Donc que on peut réduire encore le code par 2,3 fonctions je veux bien mais ça va pas être bien méchant je pense comme fonction ,je que j'appelle "faire du ménage" qu'une réflexion sur les fonctions indépendante/optimisation , les grandes lignes sont la.

    Edit :@bktero oui tu as raison ,ça devient très HS inutile de continuer enfin sur ce débat je pense.

Discussions similaires

  1. Comment bien déboguer son code ?
    Par D[r]eadLock dans le forum Débuter
    Réponses: 47
    Dernier message: 02/04/2024, 16h06
  2. [JSmooth] Bien intégrer la JRE avec son programme
    Par Ceubex dans le forum EDI et Outils pour Java
    Réponses: 0
    Dernier message: 30/03/2012, 23h01
  3. [mise en page] pour bien indenter son code
    Par bihorece dans le forum C++Builder
    Réponses: 4
    Dernier message: 06/08/2003, 16h14
  4. Mettre son programme dans Envoyer Vers ?
    Par MaTHieU_ dans le forum C++Builder
    Réponses: 11
    Dernier message: 29/07/2003, 19h09
  5. Réponses: 13
    Dernier message: 11/05/2003, 13h25

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo