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éfinir l'octet à utiliser ?


Sujet :

C

  1. #1
    Membre habitué
    Homme Profil pro
    root
    Inscrit en
    Janvier 2013
    Messages
    174
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : root

    Informations forums :
    Inscription : Janvier 2013
    Messages : 174
    Points : 144
    Points
    144
    Par défaut Définir l'octet à utiliser ?
    Salut à tous.
    Disons que je veux stocker une valeur numérique entre 0 et 200 dans une variable.

    Est-ce que je peux définir une variable de 1 octet pour cela ?
    Si oui, comment on s'y prend ?

    Pas de char.
    Le but c'est de savoir si on peut définir des variables de 1,2,3,etc octet et comment le faire.)

  2. #2
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    tu peux utiliser unsigned char, qui fait accepte au minimum les valeurs [0..255]
    Sinon, il faut regarder cette documentation sur les types communs (disponibles depuis C99)
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  3. #3
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par kripteks Voir le message
    Pas de char.
    C'est bête parce que c'est ça que tu dois utiliser...

    Tu peux suivre le lien de leternel et choisir l'uint8_t, mais il y a une chance très importante que cela soit un typedef pour.... unsigned char.

    Pour les types de tailles précises, tu peux utiliser les types uint8_t, uint16_t, uint32_t mais ils sont optionnels. Pour des longueurs intermédiaires (3 bytes par exemple), il ne te reste guère que les tableaux de bytes.

  4. #4
    Membre habitué
    Homme Profil pro
    root
    Inscrit en
    Janvier 2013
    Messages
    174
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : root

    Informations forums :
    Inscription : Janvier 2013
    Messages : 174
    Points : 144
    Points
    144
    Par défaut
    Merci.

    Je mélange un peu les choses.

    Le nombre d'octet et la valeur min-max utiliser par signed int et unsigned int est fixé par: os, cpu, c, version c ?

  5. #5
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Il existe une plage minimale légale, définit par la norme du C (qui est un traité...)
    Par ailleurs, chaque compilateur fait ce qu'il veut tant qu'il la respecte.

    La première cause de variation, c'est l'architecture du processeur (32 bits, 64 bits, micro-proc en tous genres), et l'OS (c'est surtout visible dans les grandes tailles).
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  6. #6
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Je rajouterai : par le compilateur.

  7. #7
    Responsable Systèmes


    Homme Profil pro
    Gestion de parcs informatique
    Inscrit en
    Août 2011
    Messages
    17 446
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Gestion de parcs informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Août 2011
    Messages : 17 446
    Points : 43 090
    Points
    43 090
    Par défaut
    Je rajouterais qu'une valeur numérique est normalement stocké dans un int. La taille d'un int est calé sur le mot machine du cpu de destination je crois.

    Stocker ton nombre dans un unsigned char te permettras de le stocker dans un octet maximum, mais pourrais t’empêcher d'utiliser des fonctions notamment mathématiques requérant un int.
    Ma page sur developpez.com : http://chrtophe.developpez.com/ (avec mes articles)
    Mon article sur le P2V, mon article sur le cloud
    Consultez nos FAQ : Windows, Linux, Virtualisation

  8. #8
    Membre éprouvé
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 821
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 821
    Points : 979
    Points
    979
    Par défaut
    Bonjour,
    Citation Envoyé par chrtophe Voir le message
    Stocker ton nombre dans un unsigned char te permettras de le stocker dans un octet maximum, mais pourrais t’empêcher d'utiliser des fonctions notamment mathématiques requérant un int.
    Tu peux très bien faire des opération sur un unsigned char, c'est juste que le compilateur va générer un code machine qui va transformer to unsigned char en int (ce qui peut ralentir le code si le compilo n'optimise pas => visible que sur de très gros calculs).
    Bien entendu, tu ne peux pas passer un pointeur de char à une fonction qui attend un pointeur de int.

  9. #9
    Responsable Systèmes


    Homme Profil pro
    Gestion de parcs informatique
    Inscrit en
    Août 2011
    Messages
    17 446
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Gestion de parcs informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Août 2011
    Messages : 17 446
    Points : 43 090
    Points
    43 090
    Par défaut
    c'était le sens de ce que je voulais dire

    le prob se posera avec les fonctions de math.h je pense.

    Kripteks, en C tu ne gère pas la taille des variables, c'est le compilateur qui le fait.
    Ma page sur developpez.com : http://chrtophe.developpez.com/ (avec mes articles)
    Mon article sur le P2V, mon article sur le cloud
    Consultez nos FAQ : Windows, Linux, Virtualisation

  10. #10
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    Citation Envoyé par boboss123 Voir le message
    Bien entendu, tu ne peux pas passer un pointeur de char à une fonction qui attend un pointeur de int.
    Et ce code là

    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    unsigned char my_int[4]; // or my_int[8]
     
    pow_int(2, (int) my_int);

  11. #11
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 370
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 370
    Points : 23 625
    Points
    23 625
    Par défaut
    Bonjour,

    Citation Envoyé par kripteks Voir le message
    Je mélange un peu les choses.
    Le nombre d'octet et la valeur min-max utiliser par signed int et unsigned int est fixé par: os, cpu, c, version c ?
    Pas par l'OS, sauf si celui-ci est naturellement limité en taille, par exemple si tu installes un OS 32 bits sur une machine 64. Et là encore, rien ne t'empêchera d'utiliser ton compilateur pour faire de la compilation croisée. Pour le reste, le C va définir une poignée de types entier : char, int, short int, long int, etc. et leur imposer une largeur minimale, ce qui est important car toutes les architectures ne travaillent pas au niveau de l'octet : certaines utilisent des mots de 7 ou 12 bits, d'autres ne savent pas descendre en dessous de 32. À noter que les x86, depuis le 386, travaillent artificiellement « au dessous » de 32 bits : les adresses mémoire sont exprimées en octets mais, en pratique, c'est le même mot qui est chargé depuis la mémoire et c'est le micro-processeur qui se charge d'extraire la bonne valeur. D'où l'importance de l'alignement en mémoire quand on utilise des données de 16 ou 32 bits pour ne pas charger inutilement « deux demi-mots » plutôt qu'un seul mot entier.

    « char » est le plus petit entier signé, et doit être de taille suffisante pour représenter le jeu de caractère de base défini par la norme, soit 91 caractères. Étant donné que l'octet est en général l'unité minimum manipulable par la trèsgrande majorité des micro-processeurs, un char équivaut généralement à un octet mais tu peux utiliser la macro CHAR_BIT pour t'en assurer : si celle-ci vaut « 8 », tu es sûr de manipuler la bonne taille.

    Toutefois, comme dit plus haut par leternel, il te faudra plutôt déclarer « #include <stdint.h> » et utiliser les types nouvellement définis, comme int8_t, uint8_t, int16_t, etc. La largeur de ceux-ci est indiquée dans le nom de type et est censée être garantie. Ce sont sans hésitation les types à utiliser si tu as réellement besoin d'utiliser des entiers de taille fixe, par exemple, si tu travailles sur des données à exporter.

    Pour faire court :
    — Les types natifs char, int, long, short existeront forcément sur tous les compilateurs et auront une largeur minimum garantie, mais celle-ci pourra être adaptée pour coller aux spécifications de l'architecture-cible ;
    — Les entiers standard int8_t, int16_t, etc. auront une largeur fixe garantie, mais pourront ne pas être disponibles si l'architecture-cible n'est pas capable de les prendre en charge.

  12. #12
    Membre éprouvé
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 821
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 821
    Points : 979
    Points
    979
    Par défaut
    Citation Envoyé par foetus Voir le message
    Et ce code là

    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    unsigned char my_int[4]; // or my_int[8]
     
    pow_int(2, (int*) my_int);
    A part que si tu es sur un système 64bits, il y a de grosse chance de générer un bug (dans le cas où char fait 1 octet et int 8 octets).
    Et je ne suis pas sure que dans tous les cas que l'adresse de my_int soit alignée sur une adresse divisible par sizeof(int) : si ce n'est pas le cas => bug.

    En C, tu as le droit de faire n'importe quoi mais après faut pas s'étonner que ça ne marche plus

  13. #13
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 370
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 370
    Points : 23 625
    Points
    23 625
    Par défaut
    Citation Envoyé par boboss123 Voir le message
    Et je ne suis pas sure que dans tous les cas que l'adresse de my_int soit alignée sur une adresse divisible par sizeof(int) : si ce n'est pas le cas => bug.
    L'alignement en lui-même ne provoquera pas de bug. S'il y a quelque chose de valable à cette adresse, même si on l'y a placé de façon sale, le programme pourra le récupérer. C'est juste que l'accès ne sera pas optimal et pourra nécessiter deux transactions de bus au lieu d'une.

    En C, tu as le droit de faire n'importe quoi mais après faut pas s'étonner que ça ne marche plus
    Bien résumé.

  14. #14
    Membre éprouvé
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 821
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 821
    Points : 979
    Points
    979
    Par défaut
    Citation Envoyé par Obsidian Voir le message
    L'alignement en lui-même ne provoquera pas de bug. S'il y a quelque chose de valable à cette adresse, même si on l'y a placé de façon sale, le programme pourra le récupérer. C'est juste que l'accès ne sera pas optimal et pourra nécessiter deux transactions de bus au lieu d'une.
    Sur un microcontrolleur (PIC32MX), le code suivant me lève une exception critique qui me fait planter complétement le système :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
            char a[10] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09};
            int * b = (int*)&a[1];
            printf("%i\n", *b);
    Il y a peut être des mécanismes sur PC qui évitent cela

  15. #15
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 370
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 370
    Points : 23 625
    Points
    23 625
    Par défaut
    Citation Envoyé par boboss123 Voir le message
    Sur un microcontrolleur (PIC32MX), le code suivant me lève une exception critique qui me fait planter complétement le système :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
            char a[10] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09};
            int * b = (int*)&a[1];
            printf("%i\n", *b);
    Il y a peut être des mécanismes sur PC qui évitent cela
    Effectivement, c'est une bonne démonstration de ce dont on parlait au commentaire #11. Dans mon dernier commentaire, j'étais resté à la situation la plus classique (développement sur PC). Ce qui est intéressant, c'est que c'est là quelque chose qui est propre à l'architecture cible et qu'à ma connaissance, bien que la norme évoque fréquemment les questions d'alignement, à aucun moment elle ne définit cela comme undefined behavour pour ce cas précis.

  16. #16
    Membre éprouvé
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 821
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 821
    Points : 979
    Points
    979
    Par défaut
    Pour completer ma demonstration, j'ai aussi testé avec :
    => et dans ce cas là, mon système ne plante plus : c'est donc bien un problème d'alignement

  17. #17
    Responsable Systèmes


    Homme Profil pro
    Gestion de parcs informatique
    Inscrit en
    Août 2011
    Messages
    17 446
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Gestion de parcs informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Août 2011
    Messages : 17 446
    Points : 43 090
    Points
    43 090
    Par défaut
    Sur un microcontrolleur (PIC32MX), le code suivant me lève une exception critique qui me fait planter complétement le système :
    C'est bien pour ça qu'un nombre on le met dans un int et un caractère en char.

    Sinon, il faut vraiment maitriser ou bien
    En C, tu as le droit de faire n'importe quoi mais après faut pas s'étonner que ça ne marche plus
    @boboss123 :

    le cast marchera, certes. On peut aussi faire de l'inline. J'ai failli en parler (du cast) mais je voulais pas compliquer le sujet.
    Ma page sur developpez.com : http://chrtophe.developpez.com/ (avec mes articles)
    Mon article sur le P2V, mon article sur le cloud
    Consultez nos FAQ : Windows, Linux, Virtualisation

  18. #18
    Membre éprouvé
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 821
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 821
    Points : 979
    Points
    979
    Par défaut
    Citation Envoyé par chrtophe Voir le message
    C'est bien pour ça qu'un nombre on le met dans un int et un caractère en char.
    Pas forcement, si par exemple tu as plein de variables à stocker dont la valeur est petite, le char est très utile pour économiser de l'espace mémoire (ce qui est important sur microcontrolleur)

  19. #19
    Responsable Systèmes


    Homme Profil pro
    Gestion de parcs informatique
    Inscrit en
    Août 2011
    Messages
    17 446
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Gestion de parcs informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Août 2011
    Messages : 17 446
    Points : 43 090
    Points
    43 090
    Par défaut
    Pas forcement, si par exemple tu as plein de variables à stocker dont la valeur est petite, le char est très utile pour économiser de l'espace mémoire (ce qui est important sur microcontrolleur)
    Ta réflexion a du sens, mais un compilateur digne de ce nom ne fera t'il pas ce boulot ? (avec directive de compilation par exemple)
    Ma page sur developpez.com : http://chrtophe.developpez.com/ (avec mes articles)
    Mon article sur le P2V, mon article sur le cloud
    Consultez nos FAQ : Windows, Linux, Virtualisation

  20. #20
    Membre éprouvé
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 821
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 821
    Points : 979
    Points
    979
    Par défaut
    Citation Envoyé par chrtophe Voir le message
    Ta réflexion a du sens, mais un compilateur digne de ce nom ne fera t'il pas ce boulot ? (avec directive de compilation par exemple)
    Non, il ne peut pas déterminer seul la plage de valeur du résultat d'un calcul.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    int foo(int a, int b){
       return a * b;
    }
    => comment veux-tu que le compilateur sache qu'elles sont les valeurs de a et de b que l'utilisateur va entrer ?

    Il existe juste pour les enum des paramètres (pas dispo pour tous les compilateur) qui permettent de dire au compilo que le type de l'enum doit être le plus possible : le type est défini en fonction des valeurs possibles de l'enum déclarées (car un enum est normalement un int par défaut).

    Remarque : pour info, un char peut être signé ou non signé (dépend des options du compilo)

Discussions similaires

  1. Définir dbConnection sans utiliser le fichierApp Config
    Par tinhinan6 dans le forum Windows Forms
    Réponses: 1
    Dernier message: 03/04/2014, 13h09
  2. Utilisation indice pour définir la div utilisée
    Par tijoh dans le forum jQuery
    Réponses: 2
    Dernier message: 04/07/2013, 15h57
  3. Réponses: 3
    Dernier message: 08/01/2008, 16h53
  4. [VS 2005] Comment définir la version du framework à utiliser?
    Par therock dans le forum Visual Studio
    Réponses: 1
    Dernier message: 04/08/2006, 05h08
  5. Réponses: 7
    Dernier message: 07/09/2004, 14h16

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