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 :

Disponibilité de "Solution Guide, Thinking C++"


Sujet :

C++

  1. #21
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    90
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : Algérie

    Informations forums :
    Inscription : Octobre 2005
    Messages : 90
    Par défaut
    J'avais pas pensé a poser la question avant mais, j'ai remarqué qu'on préfère toujours les expression du type que c'est pas la même chose?

  2. #22
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    Perso, je préfère l'expression avec les braquets...

    Mais cela revient en effet à la même chose:

    D'un coté, avec les braquets, tu dis "je veux l'élément à l'indice index", et de l'autre, tu dis "je veux ce qui se trouve à l'adresse (début du tableau+(index*taille de l'élément) ) "

    Et comme, l'indice index correspond à l'adresse du début du tableau + (index * taille de l'élément)...

    Maintenant, il faut savoir qu'il y a quelques situations dans lesquelles l'un est préférable à l'autre (mais sans fournir l'index, alors)...

    Tous les conteneurs de la STL qui ne fournissent pas un accès aléatoire aux éléments (donc, en gros, tous à l'exception de std::vector) et qui forcent l'utilisation d'un iterateur nécessitent le recours à (*iterateur) pour accéder au contenu.

    On peut donc estimer que l'utilisation de la syntaxe *(tableau +index) assure une meilleure homogénéité d'écriture... Mais c'est un avis que je ne partage pas forcément
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  3. #23
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Par défaut
    Citation Envoyé par disturbedID Voir le message
    Et on peux encore la faire tenir sur une ligne
    La, pour le coup, c'est illisible

    EDIT : je pense d'ailleurs que tu oublies l'incrémentation du pointeur donc pas faisable en une seule ligne.

  4. #24
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    90
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : Algérie

    Informations forums :
    Inscription : Octobre 2005
    Messages : 90
    Par défaut
    Si t[i] = *(t+i) pourquoi ce message alors?
    Citation Envoyé par Alp Voir le message
    En effet, en faisant :
    Mais bon ce n'est qu'un détail.
    Bizarre j'ai toujours cru que *(t+i) était plus rapide?
    *************************************************
    @NiamorH : Non on incrémente pas le pointeur on fait l'addition avec "lon". Mais bon c'est tellement illisible (en plus d'être sûrement moins rapide vu qu'on fait un cast a chaque fois. Donc je garde ta solution)

  5. #25
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    Il n'y a que peu de raisons que ce soit le cas, à défaut de pouvoir certifier qu'il n'y en a aucune

    Mes essais persos montrent qu'un code simple dans lequel le seul changement est la tranfsormation d'un acces en tab[i] en un acces en *(tab+i) produit exactement le même code assembleur, sous réserve, évidemment, d'utiliser les même options d'optimisation.

    Et, dans l'ensemble, ce n'est pas *si* étonnant que cela: le jeu d'instruction reste malgré tout (relativement ) limité, même si on demande explicitement d'utiliser le jeu des processeurs les plus récents

    Il est donc *relativement* logique que deux codes suivant exactement la même logique générale pour mener à un résultat identique fourniront une succession d'instructions processeurs identique ...

    Maintenant, comprenons nous bien: je me base ici sur mes observations personnelles en utilisant mon compilateur (gcc 4.2.1 en l'occurrence).

    Il n'est pas impossible que de "vieux" compilateurs (et donc moins "techniquement au point") ou que d'autres compilateurs puissent avoir des résultat différents. Et c'est la principale raison de l'"extrême prudence" de mes propos
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  6. #26
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    90
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : Algérie

    Informations forums :
    Inscription : Octobre 2005
    Messages : 90
    Par défaut
    Merci

  7. #27
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    90
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : Algérie

    Informations forums :
    Inscription : Octobre 2005
    Messages : 90
    Par défaut
    Je tiens a signaler quand même que Mr. Bruce Eckel, malgré son formidable travail a bien joué son coup, avec quelque fois des exercices sans grandes indications et où on ne voit même pas le but recherché, il arrive a bloqué le lecteur désireux de connaître la solution (souvent bête), avec juste en dessus le petit message subliminal
    Solutions to selected exercises can be found in the electronic document The Thinking in C++ Annotated Solution Guide, available for a small fee from http://www.BruceEckel.com.
    Je peux vous dire que si j'avais une MasterCard y a bien longtemps que j'aurai craqué

    exemple d'exercices le n°1 du chapitre 4 :
    # In the Standard C library, the function puts( ) prints a char array to the console (so you can say puts("hello")). Write a C program that uses puts( ) but does not include <stdio.h> or otherwise declare the function. Compile this program with your C compiler. (Some C++ compilers are not distinct from their C compilers; in this case you may need to discover a command-line flag that forces a C compilation.) Now compile it with the C++ compiler and note the difference.
    Et il ne donne même pas la déclaration de puts, comme si c'était évident qu'elle retourne un int (et si vous mettez void a la place ou quelque chose d'autre ça ne marchera pas). Et pire encore il ne dit même que c'est avec le compilateur c que ça doit marcher. Il abandonne complètement son lecteur.

    ou encore cette exercice complètement inutile :
    (Challenging) Modify FloatingAsBinary.cpp so that it prints out each part of the double as a separate group of bits. You’ll have to replace the calls to printBinary( ) with your own specialized code (which you can derive from printBinary( )) in order to do this, and you’ll also have to look up and understand the floating-point format along with the byte ordering for your compiler (this is the challenging part).
    sans commentaire
    Au mieux ça t'apprend a Googler mais ça te fais perdre du temps


    Je me console en me disant que la pauvreté et la meilleur école.

  8. #28
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Par défaut
    Citation Envoyé par disturbedID Voir le message
    Non on incrémente pas le pointeur on fait l'addition avec "lon". Mais bon c'est tellement illisible
    Ah oui exact.
    Citation Envoyé par disturbedID Voir le message
    en plus d'être sûrement moins rapide vu qu'on fait un cast a chaque fois
    Alors le static_cast est fait à la compilation, normalement il n'y a aucune perte de rapidité significative à l'éxécution. dynamic_cast est le seul cast où il y a perte de perfs.
    Par contre tu fais une addition et moi une simple incrémentation.

  9. #29
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    90
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : Algérie

    Informations forums :
    Inscription : Octobre 2005
    Messages : 90
    Par défaut
    Peut-on parler d'une simple incrémentation pour un pointeur vers un entier?

  10. #30
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    En fait, une incrémentation ne peut que difficilement être autre chose que "simple"...

    Sémantiquement parlant, le terme incrémentation signifie "ajouter 1 à la valeur de"...

    Cela signifie que, si tu as une variable numérique qui vaut 4 et que tu l'incrémente, elle ne peut pas valoir autre chose que... 5

    La seule nuance au niveau des pointeurs est que le fait de les incrémenter fournit l'adresse à laquelle l'élément suivant du type géré par le pointeur *devrait* théoriquement se trouver.
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  11. #31
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Citation Envoyé par disturbedID Voir le message
    Oui c'est ça aussi qui me gêneait, surtout ma méconnaissance du mot "range" que je croyais l'équivalent de "rang" en français. Peut être que "tranche" a la place de "limite" aurait été plus clair aussi?
    Range, je traduirai par "intervalle".
    L'équivalent de tranche serait plutôt qquelque chose comme "slice"

  12. #32
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 393
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 393
    Par défaut
    Citation Envoyé par NiamorH Voir le message
    Alors le static_cast est fait à la compilation, normalement il n'y a aucune perte de rapidité significative à l'éxécution. dynamic_cast est le seul cast où il y a perte de perfs.
    Par contre tu fais une addition et moi une simple incrémentation.
    Un cast d'un entier en entier plus petit, ou entre flottant et entier, n'est pas fait "à la compilation" et affecte les performances (surtout côté flottant<-->entier).

    Seuls le reinterpret_cast<> et le const_cast<> n'ont d'effet qu'à la compilation...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  13. #33
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Par défaut
    Tu as raison, durant la compil, un static_cast génère un peu de code, mais très optimisé, notamment des affectations qui, si elles sont effectuées sur des objets, peuvent entraîner l'appel du constructeur par copie. Sur les types de base ça reste très léger, peut-être plus lourd quand même que la différence entre addition et incrémentation, je ne sais pas.

  14. #34
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    90
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : Algérie

    Informations forums :
    Inscription : Octobre 2005
    Messages : 90
    Par défaut
    Bonjour tout le monde,
    Attention le poste risque d'être un peu longuet je m'en excuse.
    Je suis à l'exo 22 du chapitre 4.
    N.B : Stash = sorte de tableau dynamique. Stack = Pile ( )
    Créez un Stack qui contient des Stashes. Chaque Stash contiendra 5 lignes d'un fichier passé en entrée. Créez les Stashes en utilisant new. Chargez le contenu d'un fichier dans votre Stack, puis réaffichez-le dans sa forme origninale en extrayant les données de la structure Stack.
    Exo terminé mais y a quelque chose qui me gêne, c'est que si je décide de supprimer les chaîne allouée dynamiquement avec delete je rencontre une très longue erreur à l'execution
    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
    *** glibc detected *** ./exo22: free(): invalid pointer: 0xb7e2a164 ***
    ======= Backtrace: =========
    /lib/tls/i686/cmov/libc.so.6[0xb7d4cd65]
    /lib/tls/i686/cmov/libc.so.6(cfree+0x90)[0xb7d50800]
    /usr/lib/libstdc++.so.6(_ZdlPv+0x21)[0xb7f15d81]
    /usr/lib/libstdc++.so.6(_ZNSs4_Rep10_M_destroyERKSaIcE+0x1d)[0xb7ef190d]
    /usr/lib/libstdc++.so.6(_ZNSsD1Ev+0x51)[0xb7ef37b1]
    ./exo22[0x8048ec4]
    /lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe0)[0xb7cf9050]
    ./exo22(__gxx_personality_v0+0x41)[0x8048a61]
    ======= Memory map: ========
    08048000-0804a000 r-xp 00000000 16:43 2310435    /home/riad/Programmation/cpp/testString/exo22
    0804a000-0804b000 rw-p 00001000 16:43 2310435    /home/riad/Programmation/cpp/testString/exo22
    0804b000-0806c000 rw-p 0804b000 00:00 0          [heap]
    b7b00000-b7b21000 rw-p b7b00000 00:00 0 
    b7b21000-b7c00000 ---p b7b21000 00:00 0 
    b7ce2000-b7ce3000 rw-p b7ce2000 00:00 0 
    b7ce3000-b7e27000 r-xp 00000000 16:42 621387     /lib/tls/i686/cmov/libc-2.6.1.so
    b7e27000-b7e28000 r--p 00143000 16:42 621387     /lib/tls/i686/cmov/libc-2.6.1.so
    b7e28000-b7e2a000 rw-p 00144000 16:42 621387     /lib/tls/i686/cmov/libc-2.6.1.so
    b7e2a000-b7e2d000 rw-p b7e2a000 00:00 0 
    b7e2d000-b7e37000 r-xp 00000000 16:42 457878     /lib/libgcc_s.so.1
    b7e37000-b7e38000 rw-p 0000a000 16:42 457878     /lib/libgcc_s.so.1
    b7e38000-b7e39000 rw-p b7e38000 00:00 0 
    b7e39000-b7e5c000 r-xp 00000000 16:42 621391     /lib/tls/i686/cmov/libm-2.6.1.so
    b7e5c000-b7e5e000 rw-p 00023000 16:42 621391     /lib/tls/i686/cmov/libm-2.6.1.so
    b7e5e000-b7f46000 r-xp 00000000 16:42 1766046    /usr/lib/libstdc++.so.6.0.9
    b7f46000-b7f49000 r--p 000e8000 16:42 1766046    /usr/lib/libstdc++.so.6.0.9
    b7f49000-b7f4b000 rw-p 000eb000 16:42 1766046    /usr/lib/libstdc++.so.6.0.9
    b7f4b000-b7f51000 rw-p b7f4b000 00:00 0 
    b7f64000-b7f67000 rw-p b7f64000 00:00 0 
    b7f67000-b7f81000 r-xp 00000000 16:42 1520740    /lib/ld-2.6.1.so
    b7f81000-b7f83000 rw-p 00019000 16:42 1520740    /lib/ld-2.6.1.so
    bff96000-bffac000 rw-p bff96000 00:00 0          [stack]
    ffffe000-fffff000 r-xp 00000000 00:00 0          [vdso]
    Abandon (core dumped)
    et dès que je commente le delete tout marche au poile.
    Dont j'ai cerné le problème (j'ai supprimer la pile) et la il s'agit juste d'utiliser le stash pour copier les lignes une à une. puis de les afficher et j'ai le même problème. Je pose la solution du problème simplifié :
    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
    int main(int argc, char* argv[])
    {
        ifstream in("main.cpp");
        Stash tabDyn;
        tabDyn.initialize(sizeof(string*));
     
        //Fichier->Stash
        string line;
        while(getline(in, line))
            tabDyn.add(new string(line));
     
        //Affichage du fichier
        string *ligne;
        for(int i = 0; i < tabDyn.count(); i++)
        {
            ligne = (string*) tabDyn.fetch(i);
            cout << *ligne << endl;
            delete ligne;
        }
        tabDyn.cleanup();;
    }
    Voila c'est vraiment pas compliqué. Ca se passe au niveau de "delete ligne" (avant dernière). si je libère pas les string tout marche bien, sinon ça foire.

    Il faut savoir que Stash à été écrite et présentée par l'auteur lors du chapitre 4. Si vous voulez que je poste ici le Stash.cpp et Stash.h y a pas de problème.

    Si vous trouvez le message trop long où voulez plus de précisions n'hésitez pas.

  15. #35
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Théoriquement la désallocation, c'est ton tableau qui la fait, donc je ne vois pas trop ce qui se passe du tout

  16. #36
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    90
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : Algérie

    Informations forums :
    Inscription : Octobre 2005
    Messages : 90
    Par défaut
    @miles : On voulant te répondre, j'ai revu la fonction add de la class Stash, et j'ai enfin compris mon erreur et compris ce qui s'est passé, je m'explique :

    1- La classe Stash n'est qu'un tableau de char, dont on spécifie la taille du type qu'elle est sensé stocker a l'initialisation. Et la fonction add
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int Stash::add(const void* element)
    prend donc un pointeur vers l'élément qu'on veut ajouter. Or moi qui voulais stocké un pointeur vers un string je n'envoyais qu'un...pointeur vers un string alors qu'il fallait envoyer un pointeur vers un pointeur de string. Même chose pour la valeur a retourner. Donc la version corrigée :
    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
    void main(int argc, char* argv[])
    {
        ifstream in("main.cpp");
        Stash tabDyn;
        tabDyn.initialize(sizeof(string*));
     
        //Fichier->Stash
        string line;
        while(getline(in, line))
        {
            string *tempLine = new string(line);
            tabDyn.add(&tempLine);
        }
     
        //Affichage du fichier
        string *ligne;
        for(int i = 0; i < tabDyn.count(); i++)
        {
            ligne = *((string**) tabDyn.fetch(i));
            cout << *ligne << endl;
            delete ligne;
        }
        tabDyn.cleanup();;
    }
    Donc pour répondre a miles, non tabDyn.cleanup() ne fais pas tout, car, et ça tu ne pouvais pas le savoir :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void Stash::cleanup() {
      if(storage != 0) {
        //cout << "freeing storage" << endl;
        delete []storage;
      }
    } ///:~
    Elle ne fais que supprimer le tableau de char qui stockait les éléments.

    Maintenant que c'était il passé avant, et bien tout simplement en envoyant un pointeur vers un string, l'élément copié dans le tableau était le string, qui, et je viens de le remarquer ne tient que sur 4 octet et qui est donc un genre de référence vers la vrai structure stockée quelque part dans la mémoire. Donc j'avais apparement la même valeur que maintenant suaf que le delete ne marchais pas avant vu qu'on ne supprimé pas avant un vrai pointeur (en tout cas pas déclaré en tant que tel).

    Je sais pas si vous comprenez

    Si je me suis trompé n'hésitez pas.

    En tout cas Merci miles.

  17. #37
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    J'ai pas tout saisi, mais si tu as une erreur de moins, tant mieux

Discussions similaires

  1. Suppression magic quote ; solution de remplacement
    Par Xenofexs dans le forum Langage
    Réponses: 1
    Dernier message: 27/05/2014, 18h33

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