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 :

Signification de "0x" au niveau stockage.


Sujet :

C

  1. #1
    Membre Expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Par défaut Signification de "0x" au niveau stockage.
    Salut!

    Ceci:
    est il équivalent à :
    sur toute les implémentations ?

    Autrement dit est-ce que "0x01" n'est qu'une notation signifiant "le chiffre 1 en héxadécimal" et sera interprété à la compilation comme "int n = 1", ou bien est-ce que cela impose l'organisation mémoire?

    Par exemple sur une implémentation où l' "int" "1" est codé sur 2 bytes ainsi:
    est-ce que "int n = 0x01" sera stocké ainsi:
    ou ainsi:
    ?

    Merci.

  2. #2
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    La constante 1 ,en décimal, est du même type que la constante 0x1, en hexadécimal. Pour des valeurs (beaucoup) plus importantes de la constante, cela ne peut pas être toujours le cas et la réduction à un int peut donner des résultats différents.
    La valeur obtenue est indépendante de l'endian utilisé par la mémoire et donnera dans les deux cas la valeur 1
    Par exemple sur une implémentation où l' "int" "1" est codé sur 2 bytes ainsi:
    11111111 11111111
    Existe t-il une telle implémentation dans la norme ??
    est-ce que "int n = 0x01" sera stocké ainsi:
    11111111 11111111ou ainsi:
    00000000 11111111
    Ceci étant , le 0 et le 1 de l'écriture hexa ne représente que 4 bits, pas 8.

  3. #3
    Membre éclairé Avatar de Bayard
    Inscrit en
    Juin 2002
    Messages
    863
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 863
    Par défaut
    unsigned short pemet d'indiquer clairement que la variable sera stockée sur 2 octets.

    la longueur du type "unsigned int" ou "int" dépends du compilateur.

  4. #4
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par seriousme
    Autrement dit est-ce que "0x01" n'est qu'une notation signifiant "le chiffre 1 en héxadécimal" et sera interprété à la compilation comme "int n = 1",
    La manière dont les littéraux sont écrits ne change rien.

  5. #5
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par diogene
    La constante 1 ,en décimal, est du même type que la constante 0x1, en hexadécimal. Pour des valeurs (beaucoup) plus importantes de la constante, cela ne peut pas être toujours le cas et la réduction à un int peut donner des résultats différents.
    Je ne vois pas de tel cas. Tu penses à quel cas?

  6. #6
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par seriousme
    Ceci:
    est il équivalent à :
    sur toute les implémentations ?
    Pour cette valeur (1), oui. La représentation textuelle est toujours traduite de la même façon, c'est à dire en binaire : 0<...>000001

    Autrement dit est-ce que "0x01" n'est qu'une notation signifiant "le chiffre 1 en héxadécimal" et sera interprété à la compilation comme "int n = 1", ou bien est-ce que cela impose l'organisation mémoire?

    Par exemple sur une implémentation où l' "int" "1" est codé sur 2 bytes ainsi:
    Une implémentation où une telle combinaison de bits vaudrait 1 ne pourrait pas supporter le langage C.
    est-ce que "int n = 0x01" sera stocké ainsi:
    ou ainsi:
    Quelque soit la constante utilisée (1, 01, 0x1, 0x00001 etc.), la valeur binaire sera toujours 0<....>000001.

    Les combinaisons de bits que tu montres au-dessus valent respectivement 0xFF (255) et 0x0F (15). A noter qu'un int fait plutôt 16 bits (ou plus) que 8, soit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    00000000 00000000 11111111 11111111 (0x00FF)
    00000000 00000000 00000000 11111111 (0x000F)

  7. #7
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par Bayard
    unsigned short pemet d'indiquer clairement que la variable sera stockée sur 2 octets.

    la longueur du type "unsigned int" ou "int" dépends du compilateur.
    La longueur de tous les types dépends du compilateur. J'ai par exemple accès à une machine où les short font 18 bits (les char 9, les int et les long 36).

  8. #8
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Par contre, il faut savoir qu'une constante décimale 1, 256, 32768, est de type int, ce qui peut poser un problème avec l'interprétation qui en est faite si la valeur est > INT_MAX.

    Pour être portable, il est recommandé de forcer le mode 'unsigned' avec u (ou U) au dela de 32766 : 32767u. Attention aussi à ne pas dépaser INT_MAX. 1000000U n'est pas forcément défini, et il faut alors forcer en long avec l (ou L) :

    1000000L, voire 10000000UL si on dépasse LONG_MAX etc. avec long long (C99)...

    Par contre, les constantes 0... (octales) et 0x... (héxadécimales), sont toujours non signées, mais les même limitations s'appliques, et on a parfois recours à L ou LL (C99)
    Les littéraux décimaux sans suffixe ont pour type le premier qui peut représenter la valeur dans la liste: int, long int, unsigned long int.

    Les littéraux octals (octaux?) ou hexadécimaux sans suffixe ont pour type le premier qui peut représenter la valeur dans la liste: int, unsigned int, long int, unsigned long int.

    Les suffixes font la chose évidente.

    Modification pour C99: ajout de long long, et les constantes décimales sans suffixes ne sont jamais d'un type non signé.

    Les suffixes de taille sont utiles dans deux contextes, et à chaque fois pour empécher un littéral d'être interprété comme d'un type plus petit que celui désiré:
    - quand les promotions conduiraient à un mauvais type pour le résultat d'un opérateur (principalement quand les deux opérandes sont des littéraux ou pour les opérateurs assymétriques dans le traitement du type comme les décalages),
    - quand le littéral est un paramètre à une fonction variadique ou dont aucun prototype n'a été vu.

  9. #9
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Non.
    • 1 est de type int
    • 0x1 est de type unsigned int.
    Les deux sont de type int. Un littéral supérieur à INT_MAX et inférieur à UINT_MAX sera de type unsigned int s'il est octal ou hexadécimal et de type long s'il est décimal et inférieur à LONG_MAX.

  10. #10
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet
    Les deux sont de type int. Un littéral supérieur à INT_MAX et inférieur à UINT_MAX sera de type unsigned int s'il est octal ou hexadécimal et de type long s'il est décimal et inférieur à LONG_MAX.
    Ce n'est pas trop ce que j'avais conclu des discussions lues sur clc il y a quelques années, ni déduit du comportement de Borland C 3.1 (qui se trompait peut être, après tout), mais je te fais confiance.

  11. #11
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Ce n'est pas trop ce que j'avais conclu des discussions lues sur clc il y a quelques années, ni déduit du comportement de Borland C 3.1 (qui se trompait peut être, après tout), mais je te fais confiance.
    Les deux premières phrases du message 9 sont presque une traduction du texte de C90. C99 est encore plus clair: il y a un tableau a double entrée avec une colonne pour les décimaux, une colonne pour les autres, et une ligne par suffixe.

  12. #12
    Membre Expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Par défaut
    Une implémentation où une telle combinaison de bits vaudrait 1 ne pourrait pas supporter le langage C.
    D'accord, parce que la vraie question était de savoir si le test d'endianness :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    int n = 1;
    if(*(char*)(&n) == 0)
    {
    /*big endian*/
    }
    else
    {
    /*little endian*/
    }
    pourrait être mit en défaut sur une implémentation exotique.

  13. #13
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par seriousme
    D'accord, parce que la vraie question était de savoir si le test d'endianness :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    int n = 1;
    if(*(char*)(&n) == 0)
    {
    /*big endian*/
    }
    else
    {
    /*little endian*/
    }
    pourrait être mit en défaut sur une implémentation exotique.
    Oui. Il n'y en a pas que deux. Si on a des int sur 4 bytes, il y a 24 possibilités dont au moins 3 ont été utilisées par du hard et une quatrième par du soft.

  14. #14
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par seriousme
    D'accord, parce que la vraie question était de savoir si le test d'endianness :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    int n = 1;
    if(*(char*)(&n) == 0)
    {
    /*big endian*/
    }
    else
    {
    /*little endian*/
    }
    pourrait être mit en défaut sur une implémentation exotique.
    Oui, une implémentation qui ne serait ni big endian ni little endian. C'est pour ça qu'il vaut mieux faire comme ça :
    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
     
       unsigned int x = 1;
       unsigned char *p = (char *) &x;
     
       if (p[0] & 1 == 1)
       {
          /* little endian*/
       }
       else if (p[sizeof int - 1] & 1 == 1)
       {
          /* big endian*/
       }
       else
       {
          /* exotic */
       }
    Au fait, ça sert à quoi de savoir ça ? Tu n'envisages quand même pas d'écrire du code de chacal ?

  15. #15
    Membre Expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Par défaut
    Oui mais si un système "big endian" représente "1" ainsi:
    alors
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (p[0] & 1 == 1) <=> (00000000 00000000 & 00000000 00000000 == 00000000 00000000)
    ce qui vérifie la condition "little endian".

  16. #16
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par seriousme
    Oui mais si un système "big endian" représente "1" ainsi:
    alors
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (p[0] & 1 == 1) <=> (00000000 00000000 & 00000000 00000000 == 00000000 00000000)
    ce qui vérifie la condition "little endian".
    J'ai rien compris. Quel rapport entre 1 et 00000000 00000000 ?

    De toutes façon, l'endianness ne concerne pas les bits, mais les bytes. Il faut donc cesser de raisonner en binaire.

    J'ai l'impression que tu fais des confusions...

  17. #17
    Membre Expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Par défaut
    J'ai rien compris. Quel rapport entre 1 et 00000000 00000000 ?
    C'est juste théorique, si un système stocke en mémoire la valeur "1" de cette façon, le test :
    sera vérifié quelque soit son endianness.

  18. #18
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par seriousme
    C'est juste théorique, si un système stocke en mémoire la valeur "1" de cette façon, le test :
    sera vérifié quelque soit son endianness.
    Déjà répondu. Un système qui code la valeur 1 avec 00000000 00000000 ne peut pas implémenter un compilateur C standard.

    C'est soit (en supposant int de 2 bytes de 8 bits)
    00000001 00000000
    soit
    00000000 00000001
    selon l'endianness, mais en 16 bits se sera toujours
    0000000000000001
    quelque soit la machine. C'est clair ça ?
    En fait, il faut raisonner en byte, c'est plus clair :

    En supposant sizeof (int) == 2, un int valant 1 (0001) peut se coder
    00 01
    ou
    01 00
    selon l'endianness.

    Encore une fois, pourquoi as-tu besoin de cette information ?

  19. #19
    Membre Expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Par défaut
    Un système qui code la valeur 1 avec 00000000 00000000 ne peut pas implémenter un compilateur C standard.
    Existe il un document qui liste les conditions nécessaires pour implémenter le C standard ?
    Encore une fois, pourquoi as-tu besoin de cette information ?
    Question complètement théorique.

  20. #20
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par seriousme
    Existe il un document qui liste les conditions nécessaires pour implémenter le C standard ?
    Mais il ne me crois pas l'animal ! Tu as raison, il faut toujours vérifier :

    http://www.open-std.org/jtc1/sc22/wg...docs/n1124.pdf

    Have fun !

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

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