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éclaration d'entier: Respecter le type exact ?


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de tintin72
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    663
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 663
    Par défaut Déclaration d'entier: Respecter le type exact ?
    Bonjour,

    J'aurais une question d'ordre général en ce qui concerne les
    déclaration d'entier short, long, signé, non signé etc..

    Très souvent dans les exemples des livres ou sur le net les
    entiers sont généralement déclaré par un simple int, même si la variable
    ne doit contenir qu'un tout petit nombre non signé.
    J'ai donc pris l'habitude de déclarer un int dès que j'ai besoin de stocker un entier.
    Mais ce qui m'a fait tiquer c'est que lorsque j'utilise un vector de la stl par ex:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    for(int i = 0; i < monVecteur.size(); i++)
    Le compilo me met un avertissement à cause de la comparaison entre un int
    et un unsigned int (retourné par la méthode size).
    J'ai aussi quelques avertissements du même genre avec certaines librairies
    où le compilo est très pointilleux sur les types de retour.

    Aussi, j'aimerais bien me fixer une règle et m'y tenir.
    Alors est ce qu'il vaut mieux respecter scrupuleusement le type
    de valeur attendue: déclarer un unsigned char pour un petit nombre non signé,
    un short int pour un nombre signé plus important etc... ou bien
    mettre des int partout en espérant que le compilo ne se plaindra pas trop ?
    Et est ce que cela fait gagner de l'espace mémoire (et éventuellement de la vitesse) ?


    Merci d'avance.

  2. #2
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Au lieu d'écrire ce genre de boucles, fais plutôt une boucle foreach.

  3. #3
    Membre éclairé Avatar de tintin72
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    663
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 663
    Par défaut
    Je ne connaissais pas le foreach en C++, c'est bon à savoir.
    Mais ça ne répond pas vraiment à ma question.

  4. #4
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 296
    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 296
    Par défaut
    size() retourne un container<>::size_type. Soit tu utilises ce type, soit tu triches en utilisant size_t, soit tu attends le C++0x pour utiliser auto.

    Personnellement, je préfère utiliser le type officiellement retourné.
    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...

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    De prime abord, il n'est simplement "pas logique" de vouloir déclarer un entier dont tu sais pertinement que la valeur tiendra dans un char (ou dans un short) sous la forme d'un int...

    De la même manière, pourquoi aller perdre toute la partie des valeurs révolues aux nombre négatifs, si tu sais que, quoi qu'il arrive, ta valeur ne sera jamais inférieure à 0

    En cela, l'idéal reste quand même toujours de veiller à utiliser le type "le plus adéquat" pour tes variables de type entier.

    Cela, c'est pour la partie qui porte sur la pure réflexion par rapport à la situation.

    En effet, il n'est pas rare de constater qu'une valeur à la base représentée par un caractère puisse être "promue", du fait de l'implémentation du compilateur, en un int car c'est "le type le plus adapté à l'utilisation des registres du processeur"...
    Citation Envoyé par Sylvain Togni Voir le message
    Sage habitude, int est l'abréviation de integer, c-a-d entier en français.
    int est bel et bien l'abréviation de "integer", mais, il n'empeche qu'il ne sert finalement pas à grand chose de prévoir une valeur pouvant aller jusqu'à 2 milliards là où la valeur maximale attendue ne serait que 255 ou seize milles et quelques...
    Il existe des solutions pour palier à cela. Pour ma part je caste systématiquement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for(int i = 0; i < int(monVecteur.size()); i++)
    Je trouve cela plus avantageux que d'utiliser des entiers non-signés, dont le maniement est plus dangereux, surtout comme indices.
    Et tu as bien tord...

    Justement, l'utilisation d'un entier non signé lorsqu'il s'agit de manipuler des incide et largement plus sécuritaire que celle d'entiers non signés...
    En effet, si tu as un tableau "C style" classique, la variable représente l'adresse du premier élément du tableau (celui d'indice 0), et toute tentative d'acces à l'indice "-1" peut mener à des conséquences facheuses.

    N'oublie pas, en outre, que les valeurs d'indices sont d'office considérées comme des valeurs non signées, et que, dans le cas d'une architecture x86, les entiers négatifs sont traités selon le principe du complément à deux...
    Le dernier bug auquel j'ai été confronté avec eux, par exemple, c'était une fonction de ce genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void f(size_t first, size_t last)
    {
      for(size_t i = first; i <= last; ++i) {...}
    }
    A priori rien de bien méchant. A part qu'à un moment j'ai eu besoin d'inverser la boucle
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void f(size_t first, size_t last)
    {
      for(size_t i = last; i >= first; ++i) {...}
    }
    Et là boum, l'appel f(0, x) donne une boucle infinie, ce qui n'est pas évident de voir du premier coup, dans le feu de l'action d'une opération de maintenance urgente.
    Ce n'est pas parce qu'une manipulation effectuée distraitement t'a un jour posé problème que tu dois décider de te passer, justement, de l'intérêt des entiers signés...

    A la limite, j'ai même envie de dire que le fait d'utiliser des entiers non signés n'arrange rien dans ce cas... tout au plus "gagne" tu la moitié des itérations avant de te rendre compte que tu a "foiré" ta boucle.

    Dis toi bien que, si la norme a décidé d'utiliser des entiers non signés comme type de retour des méhodes size(), ce n'est vraiment pas sans raison...

    Entre autre le fait que, ainsi que je l'ai signalé, il n'est pas "sémantiquement correct" d'avoir une taille négative, sans oublier le fait que, comme il s'agit (à peu de chose près) de la valeur maximale admisible pour un entier, cela permet d'éviter les limitations qui seraient induites par l'utilisation de types permettant de représenter des valeurs moindres
    Personnellement, j'utilise int partout où j'ai besoin d'un entier sauf :
    - Si j'ai une grande quantité de données à stoker (à partir de quelques millions, typiquement), j'utilise si possible un type plus petit pour diminuer l'espace mémoire et le temps d'accès. En dehors de ça, utiliser un type plus petit risque au contraire de ralentir, int est en général le type entier le plus rapide, car correspondant à la taille des registres du processeur.
    - Si INT_MAX risque d'être trop petit, j'utiliserai un type plus grand
    - Pour manipuler des bits, j'utiliserai unsigned car les opérations bit-à-bit y son mieux définies
    Là, je suis effectivement d'accord avec toi...
    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. #6
    Membre éclairé Avatar de tintin72
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    663
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 663
    Par défaut
    De prime abord, il n'est simplement "pas logique" de vouloir déclarer un entier dont tu sais pertinement que la valeur tiendra dans un char (ou dans un short) sous la forme d'un int...
    Tout à fait d'accord, c'est d'ailleur ce raisonnement qui m'a
    incité à créer ce topic.
    En ce qui concerne les indices et indexation de tableaux containers etc...
    cela me semble logique d'utiliser des unsigned int. En effet, un tableau
    ou container ne peut pas contenir -1 élément, ça n'a pas de sens.

    Donc en résumé en conclusion on pourrait dire:
    Utiliser des entiers non signés pour les indices et indexation (tableaux containers etc...).
    Respecter le type de valeur de retour des méthodes/fonctions.

    Maintenant comment savoir dans quelle situation un int sera plus adapté à l'utilisation
    des registres du processeur ?

  7. #7
    Membre émérite

    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    717
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 717
    Par défaut
    Citation Envoyé par tintin72 Voir le message
    J'ai donc pris l'habitude de déclarer un int dès que j'ai besoin de stocker un entier.
    Sage habitude, int est l'abréviation de integer, c-a-d entier en français.

    Mais ce qui m'a fait tiquer c'est que lorsque j'utilise un vector de la stl par ex:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    for(int i = 0; i < monVecteur.size(); i++)
    Le compilo me met un avertissement à cause de la comparaison entre un int
    et un unsigned int (retourné par la méthode size).
    Il existe des solutions pour palier à cela. Pour ma part je caste systématiquement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for(int i = 0; i < int(monVecteur.size()); i++)
    Je trouve cela plus avantageux que d'utiliser des entiers non-signés, dont le maniement est plus dangereux, surtout comme indices. Le dernier bug auquel j'ai été confronté avec eux, par exemple, c'était une fonction de ce genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void f(size_t first, size_t last)
    {
      for(size_t i = first; i <= last; ++i) {...}
    }
    A priori rien de bien méchant. A part qu'à un moment j'ai eu besoin d'inverser la boucle
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void f(size_t first, size_t last)
    {
      for(size_t i = last; i >= first; ++i) {...}
    }
    Et là boum, l'appel f(0, x) donne une boucle infinie, ce qui n'est pas évident de voir du premier coup, dans le feu de l'action d'une opération de maintenance urgente.

    Alors est ce qu'il vaut mieux respecter scrupuleusement le type
    de valeur attendue: déclarer un unsigned char pour un petit nombre non signé, un short int pour un nombre signé plus important etc... ou bien
    mettre des int partout en espérant que le compilo ne se plaindra pas trop ?
    Et est ce que cela fait gagner de l'espace mémoire (et éventuellement de la vitesse) ?
    Personnellement, j'utilise int partout où j'ai besoin d'un entier sauf :
    - Si j'ai une grande quantité de données à stoker (à partir de quelques millions, typiquement), j'utilise si possible un type plus petit pour diminuer l'espace mémoire et le temps d'accès. En dehors de ça, utiliser un type plus petit risque au contraire de ralentir, int est en général le type entier le plus rapide, car correspondant à la taille des registres du processeur.
    - Si INT_MAX risque d'être trop petit, j'utiliserai un type plus grand
    - Pour manipuler des bits, j'utiliserai unsigned car les opérations bit-à-bit y son mieux définies

Discussions similaires

  1. Réponses: 3
    Dernier message: 30/09/2014, 20h37
  2. [XL-2007] Respecter un format exact de cellule à rechercher
    Par neoinfo dans le forum Macros et VBA Excel
    Réponses: 12
    Dernier message: 30/05/2013, 12h01
  3. Types entiers génériques et Types entiers fondamentaux
    Par Vilukariok dans le forum Langage
    Réponses: 11
    Dernier message: 21/06/2011, 09h37
  4. un like d'un type entier avec un type string.
    Par charrynsasi dans le forum VB.NET
    Réponses: 2
    Dernier message: 10/11/2009, 11h13
  5. Réponses: 13
    Dernier message: 25/10/2006, 16h17

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