Partage
  • Partager sur Facebook
  • Partager sur Twitter

[Exercices] Venez vous entraîner !

(v2)

    30 juin 2011 à 18:10:48

    ok je ferai un ifdef.
    par contre l define de windobe c'est quoi WIN ou un truc comme ca non ?
    • Partager sur Facebook
    • Partager sur Twitter
      30 juin 2011 à 18:33:48

      Pour Windows ?
      Voir ici.
      • Partager sur Facebook
      • Partager sur Twitter
      🍊 - Étudiant - Codeur en C | Zeste de Savoir apprenez avec une communauté | Articles  - ♡ Copying is an act of love.
        30 juin 2011 à 18:58:40

        ca m'avance pas je connait pas (ou plus) très bien windobe ...
        dit moi juste le define stp c'est _WIN32 il me semble mais je suis pas sur ;) .
        • Partager sur Facebook
        • Partager sur Twitter
          30 juin 2011 à 19:05:32

          Ben c'est écris que c'est celui-ci. o_O
          Les autres, ce sont juste des définitions spécifiques à certains compilateur et _WIN64, je te laisse deviné à quoi il sert.
          • Partager sur Facebook
          • Partager sur Twitter
          🍊 - Étudiant - Codeur en C | Zeste de Savoir apprenez avec une communauté | Articles  - ♡ Copying is an act of love.
            30 juin 2011 à 19:08:52

            y'a aussi moyen de faire sans les define : getenv("OS") renvoie "Windows_NT" sous Windows 32 ou 64...
            • Partager sur Facebook
            • Partager sur Twitter
              30 juin 2011 à 19:18:58

              et renvoi quoi sous linux ? (enfin pour l'exo on s'en fiche mais pour la culture personelle ...)

              et après il faut inclure quelle lib ?

              et c'est sur que c'est une chaine de caractères ? de plus ca doit utiliser des define en interne non ? donc ca revien au même ...
              • Partager sur Facebook
              • Partager sur Twitter
                30 juin 2011 à 19:28:28

                Mon dieu !

                Tant de messages postés, tant à répondre !

                Bon, les messages, dans l'ordre où je les lis :

                @PITETRE :

                - "afficher" est à mon avis hors de la responsabilité de la classe, cf. SRP
                - Une fonction init(), même s'il y a déjà un constructeur, c'est contraire au RAII (le wikipédia anglais est à nouveau plus rempli, mais bon ...).
                - Pour playAt, utiliser deux variables me semble exagéré. Surtout lorsqu'on sait que, si l'on prend les variables x, y et v (le nombre entre 1 et 9), ça donne v = x + 3 * y + 1 ; x = (v - 1) % 3 ; y = (v - 1) / 3. Donc une seule fonctionnalité proposée serait à mon avis mieux.
                - Pour won, renvoyer un char avec 'x' et 'o' en paramètres retour, plus une valeur prédéfinie pour le cas de pas-de-victoire, permettrait d'éviter les nombres magiques. Une enum serait encore mieux, pour les éradiquer totalement.
                - Dans Grille::Grille, la division et le modulo étant deux opérations très lourder, il serait plus utile d'avoir une double boucle :
                for (int x = 0 ; x < 3 ; ++x)
                  for (int y = 0 ; y < 3 ; ++y)
                    m_grille[y][x] = x + 3 * y + '1'; // La multiplication est beaucoup plus légère
                

                - Même remarque dans Grille::init() (au passage, il vaudrait mieux faire un choix).
                - system("clear") n'est certainement pas portable. En fait, tout appel à system() n'est pas portable.


                @@ache:

                - Pour ton cryptage de césar, tu oublies aussi les caractères a-z.
                - Si jamais tu as un caractère non inclus dans ton "alpha", tu gagneras ne exception.
                - Tant qu'à faire quelque chose de générique, autant utiliser "%alpha.length()" au lieu de "%26".


                @PITETRE: Non, le C++ n'impose pas la POO ! Là, il est àmha bien plus simple de faire avec 2/3 fonctions libres, à la limite dans un namespace, mais c'est comme si on disait qu'il fallait métaprogrammer tout simplement parce que le c++ offre la méta-prog.

                @Dumpy: Maintenant, tu sais. :) (en fait, les char sont en fait uniquement des entiers, un 'a' est converti en la valeur ASCII de a à la compilation)

                @Tous: (sur la discussion POO) Je suis personnellement contre le tout-objet. C'est bien, sans en abuser pour autant.

                @@ache:

                - Pour ton tic-tac-toe, si il y a setCase et getCase, il est inutile d' "encapsuler" Case, cf. ici.
                - Pour ce que j'en sais, un morpion n'a que 9 cases. :-° (Et utiliser la dernière case pour avoir un "\0" est inutile : on sait qu'il y a précisément 9 cases, par ailleurs il y aurait std::string qui ferait mieux ce travail).
                - Accessoirement, c'est "Joueur I à gagné" et pas gagner. ^^


                @Goten: Un rand() avec modulo, c'est très bien. Parce que, déjà, le rand() n'a pas forcément un générateur très performant, ni équilibré/aléatoire. Et, ensuite, parce qu'avec rand() % 2, avec un RAND_MAX de seulement 10000 (parce que la différence ne se fait que si RAND_MAX est pair, et qu'entre 0 et RAND_MAX il y a donc un nombre non multiple de deux d'entiers) fait un pourcentage de 5001/10001 pour '0' et 5000/10001 pour '1'. Soit environ 0.50005 pour '0' et 0.49995 pour '1'. Je pense que, surtout sachant que RAND_MAX est régulièrement supérieur à cette valeur, on peut admettre que, dans ces conditions, un rand() % 2 suffit parfaitement, surtout sachant que l'aléatoire n'est même pas vraiment indispensable. Et ça permet d'optimiser un poil en évitant les divisions de double, forcément plus lourdes.
                Surtout que RAND_MAX est régulièrement réglé à une puissance de deux moins un, et que donc ceci n'introduit pas de biais du tout.

                @PITETRE: Faux, les opérateurs sont disponibles avec les structs. Et les templates aussi.

                @ProgrammeBoy: La POO mal faite rend le code encore moins évolutif. Et l'optimisation n'est que très rarement présente en POO, par rapport à un langage impératif (ne serait-ce que la v-table). En gros, tant qu'on ne connait pas bien la POO, on n'en fait pas bien. Ce qui est paradoxal, puisque pour connaître il faut faire. Compte fake ? Inscrit pour un seul message, c'est étonnant. Mais je dis ça je ne dis rien.
                • Partager sur Facebook
                • Partager sur Twitter
                  30 juin 2011 à 20:39:13

                  double boucle moins long que modulo et division ? ca m'étonerait ... et de toute façon, si ces deux operator sont la c'est qu'il y en as besoin ...
                  • Partager sur Facebook
                  • Partager sur Twitter
                    30 juin 2011 à 21:00:43

                    Citation : Equinoxe


                    @@ache:


                    - Pour ton cryptage de césar, tu oublies aussi les caractères a-z.
                    - Si jamais tu as un caractère non inclus dans ton "alpha", tu gagneras ne exception.
                    - Tant qu'à faire quelque chose de générique, autant utiliser "%alpha.length()" au lieu de "%26".



                    @Equinoxe

                    • 1)Relit mieux le code ;)
                    • 2)Je l'ai préciser en commentaire après le code que les caractère non-alpha n'était pas géré, mais que c'était simple de le faire. Je n'ai pas présenté de code, j'ai juste donné une manière de faire plus portable. :-°
                    • 3)Oui c'est vrais. :)
                    • Partager sur Facebook
                    • Partager sur Twitter
                    🍊 - Étudiant - Codeur en C | Zeste de Savoir apprenez avec une communauté | Articles  - ♡ Copying is an act of love.
                      30 juin 2011 à 21:02:24

                      Citation : Equinoxe

                      @Goten: Un rand() avec modulo, c'est très bien.



                      Commencer par ça, c'était une grosse erreur (d'autant plus sur un topic destiné aux débutants).

                      Citation


                      Parce que, déjà, le rand() n'a pas forcément un générateur très performant, ni équilibré/aléatoire. Et, ensuite, parce qu'avec rand() % 2, avec un RAND_MAX de seulement 10000 (parce que la différence ne se fait que si RAND_MAX est pair, et qu'entre 0 et RAND_MAX il y a donc un nombre non multiple de deux d'entiers) fait un pourcentage de 5001/10001 pour '0' et 5000/10001 pour '1'. Soit environ 0.50005 pour '0' et 0.49995 pour '1'. Je pense que, surtout sachant que RAND_MAX est régulièrement supérieur à cette valeur, on peut admettre que, dans ces conditions, un rand() % 2 suffit parfaitement, surtout sachant que l'aléatoire n'est même pas vraiment indispensable. Et ça permet d'optimiser un poil en évitant les divisions de double, forcément plus lourdes.
                      Surtout que RAND_MAX est régulièrement réglé à une puissance de deux moins un, et que donc ceci n'introduit pas de biais du tout.



                      Y'a pas que ça. J'ai pas forcément envie de refaire une étude qui a déjà été faite (cf le message que j'ai posté). C'est une histoire de bonne pratique c'est tout. rand() est un _mauvais_ générateur quoiqu'il en soit, ne l'aggravons pas. (néanmoins rand est très rapide et donc adapter à certaines applications).
                      quand au % vs / quand même, faut pas pousser :).
                      • Partager sur Facebook
                      • Partager sur Twitter
                        30 juin 2011 à 21:05:47

                        Citation : Equinoxe


                        @@ache:


                        - Pour ton tic-tac-toe, si il y a setCase et getCase, il est inutile d' "encapsuler" Case, cf. ici.
                        - Pour ce que j'en sais, un morpion n'a que 9 cases. :-° (Et utiliser la dernière case pour avoir un "\0" est inutile : on sait qu'il y a précisément 9 cases, par ailleurs il y aurait std::string qui ferait mieux ce travail).
                        - Accessoirement, c'est "Joueur I à gagné" et pas gagner. ^^

                        @Equinoxe :

                        • Intéressant, sauf que j'ai pris en compte le fais que l'erreur soit possible (dans quel cas elle retourne 1). Peut-être devrais-je prendre l'habitude de mettre cette condition or de la boucle.
                        • Oui mais comme je l'ai dis, j'avais pas envie d'utiliser un string(je l'ai précisé dans les message suivant) et j'avais pensé à strcpy donc bon :-° pour éviter le segfault.
                        • Mh, oui en effet, je vais tout de même éviter les accents ;)

                        • Partager sur Facebook
                        • Partager sur Twitter
                        🍊 - Étudiant - Codeur en C | Zeste de Savoir apprenez avec une communauté | Articles  - ♡ Copying is an act of love.
                          30 juin 2011 à 21:45:41

                          @PITETRE: Au final, il y a autant d'itérations. Du coup, c'est simplement addition + multiplication vs. division + modulo.

                          @@ache :

                          1) En effet, je n'avais lu que la fonction de cryptage. Mais, si je veux envoyer un mot de passe crypté a83Bk ; je risque d'avoir des soucis au moment de l'utiliser. :-°
                          2) Comme les caractères sont forcément représentés par leur ASCII (norme c++, toussa), ce n'est pas plus portable, au final.


                          @Goten : mt19937 ? :) (Plus rapide, plus aléatoire, pour les autres). Sinon, c'est en fait qu'ici autant privilégier la performance (et entre / sur un double et % sur un int, je pense qu'il y a plusieurs dizaines de cycles ^^ ), surtout sachant qu'en fait on se fiche de l'aléatoirité. :)
                          • Partager sur Facebook
                          • Partager sur Twitter
                            30 juin 2011 à 21:46:46

                            et pis au niveau performance ca change quoi, allez 100 microsecondes ?
                            • Partager sur Facebook
                            • Partager sur Twitter
                              30 juin 2011 à 22:05:44

                              Citation : PITETRE

                              et pis au niveau performance ca change quoi, allez 100 microsecondes ?

                              T'es fou ! pas autant ! sinon, y'aurait pas moyen de faire tourner une appli 2D sans avoir un FPS de 0.01 ! ^^
                              • Partager sur Facebook
                              • Partager sur Twitter
                                30 juin 2011 à 22:08:10

                                euh 0,01 FPS ? ca fait 1 image toute les 100 seconde, ca fait pas beaucoup ...
                                déjà 10 FPS c'est pas mal du tout ^^
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  30 juin 2011 à 22:15:53

                                  germino : ajout de quelques auteurs (Nanoc principalement)
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    30 juin 2011 à 22:27:48

                                    Citation : Equinoxe

                                    @@ache :


                                    1) En effet, je n'avais lu que la fonction de cryptage. Mais, si je veux envoyer un mot de passe crypté a83Bk ; je risque d'avoir des soucis au moment de l'utiliser. :-°
                                    2) Comme les caractères sont forcément représentés par leur ASCII (norme c++, toussa), ce n'est pas plus portable, au final.

                                    @ Equinoxe:

                                    • Comme je l'ai dis, c'est le principe qui est intéressant.
                                    • Si justement, c'est portable. Même si on utilise l'EBCDIC.

                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                    🍊 - Étudiant - Codeur en C | Zeste de Savoir apprenez avec une communauté | Articles  - ♡ Copying is an act of love.
                                      30 juin 2011 à 23:04:40

                                      Citation : Equinoxe

                                      @Goten : mt19937 ? :)


                                      Par exemple ouai. Sauf que ça entraine des dépendances (qui peuvent être assez lourde) vu qu'il est loin d'être trivial.

                                      Pour le reste, non, je dis juste que c'est de la micro micro optimisation. (comprend, qui n'a pas lieu d'être).
                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        30 juin 2011 à 23:20:31

                                        Bonsoir à tous ! :)

                                        J'ai tenté de réaliser un des exercices, celui du Cowsay !
                                        Bon, j'ai pas honte de le dire, j'ai pas réussis à le faire :p (Alors que la correction de Nanoc m'a parue simple, même si cela demandait un peu de réflexion)

                                        Mais justement, dans cette correction, il y a une partie que je n'arrive pas à comprendre :o :
                                        int main(int argc, char *argv[])
                                        {
                                            if (argc < 2) //On affiche un message d'erreur si l'utilisateur n'a pas donne d'argument
                                            {
                                                cout << "Le programme s'utilise de la maniere suivante :\n" << argv[0] << " \"phrase a afficher\"" << endl;
                                                return 0;  //et on termine le programme
                                            }
                                        


                                        Que représente ce if ?

                                        A chaque fois que je tente de lancer le programme, le message d'erreur s'affiche (Le programme blablabla, [ici il m'indique l'emplacement de l'.exe]) et se ferme :pirate:

                                        Bon ok, donc je l'enlève ce if, je me dit "Allez hop, on va enfin le tester son petit programme", et BAM ! Error :colere: !

                                        J'en déduit que c'est la ligne
                                        string phrase=argv[1];
                                        

                                        qui fait planter le programme car je ne l'ai jamais vue auparavant.

                                        Alors ma grande question est :
                                        -Comment se fait-il que le programme s'arrête/plante arrivé à ces lignes ?

                                        Merci d'avance ;)
                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          30 juin 2011 à 23:58:34

                                          Bonsoir !

                                          Tout d'abord, le cowsay est conçu pour être utilisé en ligne de commande. C'est pour ça que les arguments du main sont utilisés (ici le if permet de vérifier si le nombre d'argument(s) passé au programme est correct, soit la variable argc qui représente le nombre d'entrées dans argv).

                                          Je t'invite à lire ce cours pour répondre à tes questions.
                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                            1 juillet 2011 à 10:03:46

                                            C'est vrai que pour son premier exercice, Nanoc n'y est pas allé avec le dos de la cuillère en ajoutant les arguments du main...
                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                            Anonyme
                                              1 juillet 2011 à 10:14:18

                                              Citation : germino

                                              y'a aussi moyen de faire sans les define : getenv("OS") renvoie "Windows_NT" sous Windows 32 ou 64...


                                              L'ennui, c'est que ce n'est pas utilisable pour l'inclusion des header particuliers à certain OS (unistd.h, windows.h, etc)

                                              Citation : PITETRE

                                              et c'est sur que c'est une chaine de caractères ? de plus ca doit utiliser des define en interne non ? donc ca revien au même ...

                                              Nan, ca recupères des variables d'environnement... Ici, la variable d'environnement OS. Tape env sous unix ou set sous windows dans un terminal pour les afficher.
                                              • Partager sur Facebook
                                              • Partager sur Twitter
                                                1 juillet 2011 à 10:20:58

                                                Citation : youyou

                                                Citation : germino

                                                y'a aussi moyen de faire sans les define : getenv("OS") renvoie "Windows_NT" sous Windows 32 ou 64...


                                                L'ennui, c'est que ce n'est pas utilisable pour l'inclusion des header particuliers à certain OS (unistd.h, windows.h, etc)



                                                C'est à dire ? Un exemple ?

                                                Ah, j'oubliais, il faut inclure <cstdlib>
                                                • Partager sur Facebook
                                                • Partager sur Twitter
                                                  1 juillet 2011 à 10:35:47

                                                  Citation : germino

                                                  Citation : youyou

                                                  Citation : germino

                                                  y'a aussi moyen de faire sans les define : getenv("OS") renvoie "Windows_NT" sous Windows 32 ou 64...


                                                  L'ennui, c'est que ce n'est pas utilisable pour l'inclusion des header particuliers à certain OS (unistd.h, windows.h, etc)



                                                  C'est à dire ? Un exemple ?

                                                  Ah, j'oubliais, il faut inclure <cstdlib>



                                                  #ifdef _WIN32
                                                    #include <windows.h>
                                                  #else
                                                    #include <unistd.h>
                                                  #endif
                                                  


                                                  • Partager sur Facebook
                                                  • Partager sur Twitter
                                                    1 juillet 2011 à 10:40:33

                                                    Ah ben oui. En fait, cette fonction elle est bien quand tu veux utiliser system(); Pour le reste, j'en conviens, c'est pas terrible...
                                                    • Partager sur Facebook
                                                    • Partager sur Twitter
                                                      1 juillet 2011 à 12:55:39

                                                      @PITETRE: En effet, sûrement même pas. Mais c'est surtout pour une affaire de lisibilité, personnellement j'aime bien remplir mon tableau avec des indices simples, quitte à avoir une valeur plus complexe à calculer. Et ça permet de n'avoir qu'un calcul à faire : 3y+x. Et il est aisément vérifié qu'il n'y a pas d'erreur dans la formule. :)
                                                      (Et, au passage, germino a plus ou moins raison, on doit perdre (valeur au pif) 150 cycles (en considérant modulo/division à 90, addition à 10 et multiplication à 20, ce qui fait une perte d'environ, sur un processeur à 1GHz, <math>\(1.5\times10^{-7}\)</math> secondes. On est loin des 100ms. ^^ )
                                                      Si on parle d'optimisations vraiment bas niveau, on pourrait remplacer x*3 par x<<1+x ; puisque :
                                                      <math>\((x \times 3)_{10} = (x \times 11)_2\)</math>
                                                      <math>\((x \times 11)_2 = (x \times 10 + x \times 1)_2\)</math>
                                                      <math>\((x \times 10)_2 = (x << 1)_2\ \ \ \ et\ \ \ \ (x \times 1)_2 = x\)</math>
                                                      <math>\(donc\ \ \ \ (x \times 3)_{10} = ([x << 1] + x)_2\)</math>
                                                      Donc on pourrait avoir pour formule : <math>\(tab[y][x] = (y << 1) + y + x + 1\)</math>, car tout nombre est manipulable en base 2 en informatique. Et ce serait encore un poil plus micro-optimisé. (dédicace spéciale Goten. :p )

                                                      @@ache : Pour l'EBCDIC, il faudrait vraiment le vouloir.
                                                      Par ailleurs, si on voulait *vraiment* un cryptage de césar portable, il faudrait simplement ne pas se préoccuper de renvoyer des caractères non affichables, et simplement faire : v = v + decalage;. Le débordement nous renvoyant automatiquement à l'autre bout, on est sûr de pouvoir faire fonctionner le programme, aux seules conditions que :
                                                      - Un fichier crypté ne voyage pas d'une plate-forme ASCII à une EBCDIC (par exemple). Mais c'est déjà le cas pour un fichier texte normal.
                                                      - Un cryptage se réalise sans c/c d l'utilisateur, mais directement par des flux redirigés.

                                                      @Goten : En fait, ce que je critique dans le passage en double, c'est surtout la double conversion (int->double->int), et les calculs beaucoup plus compliqués qui, à mon avis, ne servent qu'à gagner un poil d'aléatoire, inutile dans ces conditions (gras pour les autres qui pourraient lire ce message).
                                                      En fait, on est d'accord, mais pour une raison de bonnes pratiques, il vaut en effet mieux montrer la "vraie" formule d'aléatoire, qui l'avantage de consrver un aléatoire exactement aussi aléatoire que rand() (aux imprécisions de calcul de double près. ^^ )

                                                      @Uchizaki : En fait, c'est simplement que le cowsay est peu facilement utilisable sur windows. Il faudrait l'utiliser comme ceci (après avoir ouvert une console, attention à ne pas avoir d'espace dans le nomm de l'executable) :
                                                      cd "[Le dossier de l'executable]"
                                                      [Le nom de l'executable avec le .exe au bout] "[La phrase à cowsay-er]"


                                                      @youyou, germino : Personnellement, je préfère utiliser les defines. En effet, elles évitent une (lourde) vérification à l'exécution. Et puis, sous linux, je peux m'amuser à mettre la variable d'environnement à Windows NT, et je fais planter ton programme. ^^
                                                      En plus, ça risque d'ouvrir une faille.

                                                      Et puis, vous avez un cas d'utilisation du getenv où le #ifdef ne fonctionnerait pas ? (A part le cas où on veut afficher l'OS, et encore, c'est faisable.)
                                                      • Partager sur Facebook
                                                      • Partager sur Twitter
                                                        1 juillet 2011 à 13:00:21

                                                        Dans tous les cas, ceci est un exercice, J'ai juste fais ce code histoire d'avoir un code un peu plus portable. Après, jamais celui-ci ne devrait être utilisé dans des conditions normales ;)
                                                        • Partager sur Facebook
                                                        • Partager sur Twitter
                                                        🍊 - Étudiant - Codeur en C | Zeste de Savoir apprenez avec une communauté | Articles  - ♡ Copying is an act of love.
                                                          1 juillet 2011 à 13:39:03

                                                          je sais pas pour les calculs mais en tout cas je sais qu'en traitement d'image (j'utilise openCV) on dit que c'est fluide (ca signifie parfaitement donc moins ca reste correcte) quand le nombre de frames par seconde est de 30 FPS. et comme on as plein de calcul à faire sur les images on essaye d'avoir le FPS le plus petit possible (du coup je compte lire le tuto sur l'optimisation de calculs dans la partie algorithmie).
                                                          • Partager sur Facebook
                                                          • Partager sur Twitter
                                                            1 juillet 2011 à 16:17:27

                                                            Citation : Equinoxe


                                                            Si on parle d'optimisations vraiment bas niveau, on pourrait remplacer x*3 par x<<1+x ; puisque :
                                                            manipulable en base 2 en informatique. Et ce serait encore un poil plus micro-optimisé.



                                                            C'est là que tu te trompes, ce genre de chose c'est du voodoo rien d'autres. Oui tu gagnerais à faire ça (note le conditionnel)... tu gagnerais si on vivait dans les années 60. De nos jours ton compilo est bien plus efficace que toi pour faire ce genre de chose et le fera mieux et sûrement même plus agressivement. Autant garder quelque chose de lisible ;).
                                                            • Partager sur Facebook
                                                            • Partager sur Twitter

                                                            [Exercices] Venez vous entraîner !

                                                            × 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.
                                                            • Editeur
                                                            • Markdown