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 :

[Débutant] Afficher 3 variables à partir d'un fichier ?


Sujet :

C++

  1. #61
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    La FAQ n'indique pas pourquoi il faut éviter les casts C.

    La réponse est selon moi : Parce qu'ils peuvent tout faire. Y compris n'importe quoi.
    En convertissant un pointeur vers un autre avec un cast C, tu n'auras jamais d'erreur ou d'avertissement. Y compris si tu fais une grosse bêtise, comme "oublier" le qualificateur const d'un pointeur (tous les casts C++ te donneront une erreur, sauf const_cast<>() qui est fait pour ça) ou downcaster un pointeur d'une classe vers une class qui en fait n'est pas une classe dérivée (static_cast<> signalera l'erreur), etc.

    De plus, les opérateurs de cast peuvent faire l'objet de recherche (par exemple: retrouver tous les const_cast d'un projet), tandis que c'est impossible pour les casts C.
    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.

  2. #62
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 112
    Points : 44
    Points
    44
    Par défaut
    Dans la FAQ, rien n'explique ce que c'est que "cast" tout cours, il y a juste une comparaison avec le C mais j'ai jamais entendu parler de cast pour le C, encore.


    Quant à const, j'ai toujours pas compris l'intérêt d'avoir une variable constante, ces deux termes sont complètements contradictoirs pour un débutant.

  3. #63
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Dans la FAQ, rien n'explique ce que c'est que "cast" tout cours, il y a juste une comparaison avec le C mais j'ai jamais entendu parler de cast pour le C, encore.
    Cast signifie conversion.

    Quant à const, j'ai toujours pas compris l'intérêt d'avoir une variable constante, ces deux termes sont complètements contradictoirs pour un débutant.
    En effet, "variable constante" n'a aucun sens. const sert à définir une constante, point barre.

  4. #64
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    const a un intéret primordial dans le cas de pointeurs ou de références, surtout en paramètre de fonction.

    Et non, il n'y a pas que des "constantes" : On ne peut pas vraiment appeler une "constante" une valeur const calculée dynamiquement dans une fonction. Ça reste une variable avec un vrai emplacement mémoire, mais elle ne peut être modifiée une fois initialisée.
    En fait, le terme non-modifiable serait préférable à "constant".
    Surtout que dans un langage orienté objet, on peut aussi créer un objet const: Il reste absolument non-modifiable de sa création à sa destruction.
    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.

  5. #65
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    En fait, le mot clé const, c'est une promesse faite au compilateur:

    Tu lui promets de ne pas essayer de modifier ce que tu as déclaré const.

    Et bien sur, il rechigne s'il se rend compte que tu... ne tiens pas ta promesse...

    Ou, ainsi que l'a dit medinoc, que tu t'engages à n'accéder à l'élément "qu'en lecture seule" ...
    Tu peux donc l'utiliser à plusieurs sauces:

    Pour définir une valeur constante sous la forme d'un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const float pi=3.1415926;
    qui reviendrait *à peu pres* au meme qu'un
    à ceci près qu'il y a une vérification du type dans la première que tu n'a pas dans la seconde (si tu essaye const int pi=3.14... le compilo ne sera pas contant )

    Au niveau des pointeurs, tu peux l'utiliser de deux manières:
    - comme pointeur sur un objet constant
    - comme pointeur constant sur un objet constant

    La différence, c'est que, comme pointeur sur un objet constant, ca revient à dire "je ne promet pas que je ne ferai pas pointer le pointeur sur un autre objet (de meme type) mais je promet de ne pas modifier l'objet pointé" alors que le pointeur constant sur objet constant est la promesse, non seulement de ne pas tenter de modifier l'objet pointé, mais aussi de ne pas faire pointer le pointeur sur un autre objet.

    Au niveau des références, cela signifie que tu t'engages à ne pas modifier l'objet qui est aliasé (grosso modo la meme chose que le pointeur sur objet constant... sauf que l'alias en lui meme n'est pas modifiable )

    Enfin, au niveau des fonctions membres d'une classe, cela signifie que tu t'engages à ce que la fonction ne modifie pas la classe: elle peut travailler avec différents membres de la classe et avec des paramètres, mais les différentes valeurs seront identique avant et apres appel de la fonction.

    En soi, on *peut* estimer que cela ne sert pas à grand chose (d'autant plus que ca ne change en rien la vitesse d'exécution)... mais c'est oublier que l'erreur est humaine... et que tu peux aussi en commettre

    Il n'est pas rare, surtout sur les projets qui s'étalent sur un temps certain, que l'on oublie avoir décidé que telle ou telle valeur ne devait pas etre modifiée ou que telle ou telle fonction ne devait pas modifier les arguments passés ou les valeurs de la classe dont la fonction fait partie...

    Et du coup, il *peut arriver* que reparcourrant le code, on se dise qu'il serait peut etre intéressant de provoquer tel ou tel changement de valeur...

    Si tu n'a pas défini une valeur ne devant pas etre modifiée comme constante... le compilateur ne verra aucun problème lorsque tu décideras de la modifier... et là... les problèmes peuvent apparaitre dans les fonctions qui utilisent la fonction/valeur en se disant qu'elle n'est pas modifée... avec les incohérences que cela peut engendrer...

    Si, par contre, tu déclares toutes les valeurs qui n'ont pas à etre modifiées comme constante, le compilateur te signalera si tu ne respecte pas tes engagements, et tu sera donc en mesure d'assurer une plus grande cohérence au fur et à mesure des changements
    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. #66
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 275
    Points : 10 985
    Points
    10 985
    Par défaut
    Si la FAQ est revenue, chapitre des références sur le C++ -> dinkumware => tu auras la signature de toutes les fonctions (libres comme membre de la SL).

    Truc "rigolo" au sujet des casts à la C. Convertir d'un pointeur vers un autre passera comme un reinterpret_cast si jamais un des deux types pointés n'est pas définit -- i.e. si on possède uniquement des déclarations anticipées, au moins le static_cast nous engueule.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  7. #67
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 112
    Points : 44
    Points
    44
    Par défaut
    On pourrait aussi utiliser une variable dont on se fait, à soi-même, la promesse de ne jamais modifier.

    Mais j'imagine que la différence est dans le langage machine après compilation et que "const" prend juste la place d'une adresse à appeller ou un truc dans le genre ?

  8. #68
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par Nikolas
    On pourrait aussi utiliser une variable dont on se fait, à soi-même, la promesse de ne jamais modifier.

    Mais j'imagine que la différence est dans le langage machine après compilation et que "const" prend juste la place d'une adresse à appeller ou un truc dans le genre ?
    Le problème, c'est que la promesse que tu te fais de ne pas modifier la variable, tu peux l'avoir oubliée dans un mois et que, le type qui travaille avec toi peut tout simplement... ne pas etre au courent...

    Il n'est pas exclu (à vérifier) que ta variable const soit mise dans la partie "read only" de l'adresse et, le gros avantage que j'ai déjà signalé, c'est que, justement, si tu modifie une valeur déclarée const (ou qu'une fonction constante modifie dans son bloc d'intruction) la compilation sera arrêtée, et donc l'exécution impossible...

    Il faut bien te dire qu'il est toujours plus facile de trouver une erreur qui apparait à la compilation - du genre "vairiable is not define parce que le nom est "variable"", "variable is const and you can't modify it", ou "missing ; before ..." ...- que de retrouver l'erreur qui fait planter le programme à l'exécution ... parce que, dans ta tete, la variable n'était pas destinée à etre modifiée et que, en pratique, tu l'as modifiée...

    Tout comme, en C, il est important de tester de manière systématique que le résultat de malloc a bien réussi, comme "garde fous" destiné à éviter les problème au cas où ca "foire" (et bien que ce test ne soit efficace qu'à l'exécution), il est tout autant nécessaire... de signaler clairement les valeurs qui ne sont pas sensée etre modifiée...
    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

  9. #69
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    J'aurais d'ailleurs tendance à ajouter une chose:

    Meme si tu tapes "à deux doigts" et que tu ne connais pas le clavier, avec les éditeurs de textes qui proposent l'auto complétion (et qui sont le cas de la plupart des EDI) tu mettra quoi une seconde maximum à écrire le mot const

    A ton avis, combien te temps mettra tu à trouver que telle variable n'aurait jamais du etre modifiée à l'exécution

    Il faut bien etre conscient que le gros du "retard" lors de la conception est pris... au débuggage...

    Bien sur, il y a les différents essais de compilations qui échouent parce que "tes doigts sont trop gros", et que tu a appuyé sur z au lieu de a ou parce que tu as oublié un point virgule...

    Mais ca, ce sont des erreurs très faciles à retrouver et à corriger...

    Le gros du retard sera pris lorsque ton application "semblera fonctionner" mais que, d'une manière ou d'une autre, un comportement agira différemment que ce pour quoi il a été prévu dans le reste du code...

    A ce moment là, il s'agira de passer au débugger, de tester les valeurs d'adresse des variable, de voir si on ne "sort pas" de la fourchette d'adresse valide et que la valeur d'une adresse donnée correspond à ce que l'on en attend... et ca, ca prend énormément de temps...

    Je le signale très souvent: la solution la plus simple est toujours la meilleure...

    Et, dans le cas qui nous occupe, il est plus facile d'avoir une erreur "vous essayez de modifier une valeur constante" plutot que de commencer à chercher cette modification au moment de l'exécution, "simplement" parce que l'on n'a pas pris la peine de déclarer la valeur constante
    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

  10. #70
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 112
    Points : 44
    Points
    44
    Par défaut
    A ce niveau là, j'avais déjà compris avec ta précedente réponse, tu es très clair, koala01, c'est inévitablement plus intéressant pour l'organisation et la fiabilité du travail sur le code, mais c'est au niveau langage machine que je me demande s'il y a une différence importante, juste une curiosité (sans trop d'interêt quand on y réfléchi.)


    Pour revenir sur cast, je ne comprends pas ce qu'il "converti" dans le paramètre.

    Qu'est-ce que, concrètement, le transtypage reinterpret_cast<char*> permet de particulier, est-ce qu'il va "choisir" (je pige toujours pas son rôle) le meilleur type dans le paramètre de iostream::read ? Et dans le cas présent du code ci-dessous, on aura un char au lieu d'un int... c'est beaucoup trop flou pour moi cette histoire, je comprends pas ce que ça change en pratique, la FAQ ne répond pas du tout à cette question et le dictionnaire est trop généraliste dans sa définition.

    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
    #include <cstdlib>
    #include <iostream>
    #include <fstream>
     
    using namespace std;
     
    int main()
    {
        ifstream fichierEntree ("fichier.test", ios::binary);
     
        if (fichierEntree.is_open())
        {
                   unsigned int nombreFlt = 0;
                   float flottant = 0;
     
                   fichierEntree.read(reinterpret_cast<char*> (&nombreFlt), 2);
                   cout << nombreFlt << " flottant";
     
                   if (nombreFlt > 1) {cout << "s";}
                   cout << " au total\n" << endl;
     
     
                   for (long i = 0 ; i < nombreFlt ; i++)
                   {
                        fichierEntree.read(reinterpret_cast<char*> (&flottant), 4);
                        cout << (i + 1) << "\t" << flottant << endl;
                   }
                   cout << endl;
     
                   fichierEntree.close();
        }
     
        else
        {
            cout << "Fichier introuvable !" << endl;
        }
     
        system("pause");
        return 0;
    }

  11. #71
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    C'est bien moins philosophique que ça : reinterpret_cast va juste dire au compilo "tiens tu vois cette pomme ? et bien je voudrais que tu la traites comme si c'était une poire à partir de maintenant". Au niveau code compilé, ça ne change strictement rien, et aucune conversion n'est faite à l'exécution.
    Dans le cas de la fonction read, qui écrit une séquence d'octets quelconques, il fallait bien déterminer un type pour le paramètre, et ensuite caster ce qu'on lui envoie pour qu'il corresponde à ce type. Ils auraient aussi pu prendre void* par exemple, qui lui n'aurait pas nécessité de cast explicite. Ou encore, ils auraient pu faire une fonction template (solution donnée dans la FAQ d'ailleurs), ce qui permet de déduire la taille sans la donner explicitement.

Discussions similaires

  1. Réponses: 4
    Dernier message: 15/05/2008, 09h29
  2. [Débutante] Extraire des données à partir d'un fichier html avec xsl
    Par sab_etudianteBTS dans le forum XSL/XSLT/XPATH
    Réponses: 3
    Dernier message: 11/03/2008, 09h10
  3. utiliser xslt pour afficher du texte à partir d'un fichier xml
    Par med_ellouze dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 23/08/2007, 14h52
  4. Réponses: 5
    Dernier message: 08/08/2007, 16h44
  5. Réponses: 4
    Dernier message: 19/03/2006, 15h20

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