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 :

Travailler avec des bytes


Sujet :

C

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 7
    Par défaut Travailler avec des bytes
    Bonjour,

    J'ai un buffer de bytes en C.

    J'ai trouver sous java que pour transformer un byte en entier on utilise :
    (buffer[0] & 0xff) | ((buffer[1] & 0xff) << 8) | ((buffer[2] & 0xff) << 16) | (buffer[3] << 24)

    Est-ce la même chose en C? Et si oui, pourriez-vous m'expliquer cette syntaxe?

    Merci d'avance,
    Raoul

  2. #2
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Salut,

    Le type bytes d'existe pas en C et tu peux utiliser unsigned char. Voilà comment on peux procéder pour convertir un tableau de 4 unsigned char en un entier:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #include <stdio.h>
    #include <stdlib.h>
     
    int main(void)
    {
        unsigned char tab[4] = {0, 1}; /* correspond au mot 0x100 i.e 256 */
        int nombre;
     
        nombre = *(int *)tab; /* Convertion du tableau en un entier de type int */
     
        printf("Le nombre obtenu est %d\n", nombre);
     
        return EXIT_SUCCESS;
    }
    Cette méthode n'est pas portable et fonctionne sur un système Little Endian. La méthode que tu propose a l'avantage d'être portable, dans la mesure ou un int est représenté sur au moins 32 bits (int est toujours représenté avec 32 bits en Java. La norme C, malheureusement, garantit que la valeur max d'un int est 32767). Pour la suite, je suppose qu'un entier de type int est représenté sur 32 bits (Au besoin, on peut utilisé le type long).

    En ce qui concerne la syntaxe que tu as donné, mettons que buffer[1] contient la valeur 16 i.e 00010000 en binaire i.e 0x10:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int nombre = 0;
    nombre = (buffer[1] & 0xff) << 8;
    nombre reçoit la valeur 0x100. Si on décompose ce qui se passe:
    1. 0xff est une constante entière de type int i.e 0x000000ff
    2. buffer[1] est converti en entier 32bits i.e. 0x00000010
    3. Les 3 octets de poids fort de cette valeur sont mis à 0 (ici, 0xFF joue le role de masque). On obtient 0x00000010
    4. On décale le pattern de bits de 8 position vers la gauche et on obtient 0x100

    Maintenant, si on prend:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int nombre = 0;
    nombre = ((buffer[0] & 0xFF) << 8) | (buffer[0] & 0xff);
    Si on suppose que buffer[0] contient la valeur 0xA0 codée sur 8 bits non signés. L'expression ci-dessus est équivalente à:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int nombre = 0;
    nombre = 0x00000100 | 0x000000A0;
    Et nombre prend la valeur 0x000001A0. L'opérateur | correspond à un ET bit à bit.

    Maintenant, il n'y a pas de types non signés en Java, ce qui oblige d'écrire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int nombre = (buffer[0] & 0xFF) | ((buffer[1] & 0xFF) << 8) | ((buffer[2] & 0xFF) << 16) | ((buffer[3] & 0xFF) << 24);
    En effet, lorsqu'on transforme un octet signé valant 0xA0 en entier 32 bits:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    int nombre = 0;
    signed char un_byte = 0xA0;
    nombre = un_byte; /* nombre prend la valeur 0xFFFFFFA0 */
    Ainsi, l'utilisation du masque devient évidente:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    nombre = un_byte & 0xFF; /* nombre prend la valeur 0x000000A0 */
    En conclusion, il est possible d'alléger la syntaxe utilisée par Java en C, en déclarant buffer comme un tableau de unsigned char:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    nombre = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24);


    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  3. #3
    Membre émérite

    Profil pro
    Inscrit en
    Août 2003
    Messages
    878
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 878
    Par défaut
    Citation Envoyé par mujigka
    [...] Pour la suite, je suppose qu'un entier de type int est représenté sur 32 bits (Au besoin, on peut utilisé le type long). [...]
    Au besoin, on peut aussi utiliser uint32_t (après un "#include <stdint.h>"), ce qui permet d'éviter les suppositions

  4. #4
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Citation Envoyé par David.Schris
    Au besoin, on peut aussi utiliser uint32_t (après un "#include <stdint.h>"), ce qui permet d'éviter les suppositions
    Merci pour la précision, ça existe depuis C90? Je ne trouve rien à ce sujet dans K&R2. Pas de trace de stdint.h non plus dans "The Standard C Library" de Plauger non plus.

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  5. #5
    Rédacteur

    Avatar de gege2061
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2004
    Messages
    5 840
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2004
    Messages : 5 840
    Par défaut
    Citation Envoyé par mujigka
    Merci pour la précision, ça existe depuis C90? Je ne trouve rien à ce sujet dans K&R2. Pas de trace de stdint.h non plus dans "The Standard C Library" de Plauger non plus.

    Thierry
    C99 : Les types entiers étendus

  6. #6
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Citation Envoyé par gege2061
    Désolé de mon ignorance, je n'utilise pratiquement jamais les extensions C99... Je vais relire 7 fois ton article à haute voix (je suis puni) pour me remémorer tout ça et que ça reste cette fois.

    Meilleures salutations

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  7. #7
    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 mujigka
    Merci pour la précision, ça existe depuis C90? Je ne trouve rien à ce sujet dans K&R2. Pas de trace de stdint.h non plus dans "The Standard C Library" de Plauger non plus.
    C99 et c'est pas portable.

  8. #8
    Membre émérite

    Profil pro
    Inscrit en
    Août 2003
    Messages
    878
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 878
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    C99 et c'est pas portable.
    Qu'est-ce qui n'est pas portable ?

    Citation Envoyé par [url]http://emmanuel-delahaye.developpez.com/notes.htm#standard[/url]
    Du code source portable est censé, une fois compilé, se comporter de la même façon quelle que soit la plateforme.
    "Mon" "uint32_t", une fois compilé, il va bien se comporter de la même façon quelle que soit la plateforme, non ?
    Il me semblait d'ailleurs que c'était un peu le but de l'uint32_t : qu'il se comporte comme un entier non signé sur 32 bits quelle que soit la plateforme. Sinon : quel intérêt ?

  9. #9
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Citation Envoyé par David.Schris
    Qu'est-ce qui n'est pas portable ?

    "Mon" "uint32_t", une fois compilé, il va bien se comporter de la même façon quelle que soit la plateforme, non ?
    Il me semblait d'ailleurs que c'était un peu le but de l'uint32_t : qu'il se comporte comme un entier non signé sur 32 bits quelle que soit la plateforme. Sinon : quel intérêt ?
    Mais il faut d'abord être certain que ton code compile sur toutes les plateformes. Ce qui n'est pas portable, c'est que C99 n'est pas implantée par tout les compilateurs, et loin de là! Microsoft a même pris la décision de ne pas l'implanter du tout dans son propre compilateur. Voici une vue d'ensemble du status de l'implantation de C99 avec gcc.

    En attendant un meilleur support de la norme, C99 n'est pas encore considéré comme portable, et j'évite pour le moment d'utiliser les outils qu'elle fournit

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  10. #10
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    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 397
    Par défaut
    Ce n'est pas portable car ça ne change rien aux problèmes d'endianness qui pourrissent le code de mujigka.
    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.

  11. #11
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Citation Envoyé par Médinoc
    Ce n'est pas portable car ça ne change rien aux problèmes d'endianness qui pourrissent le code de mujigka.
    J'ai indiqué de manière explicite que le 1er code proposé posait des problème d'endianness, et donc de portabilité. Rien de nouveau sous le soleil, donc... Je peux effacer ce bout de code, si vous pensez qu'il peux induire le lecteur en erreur. Dans le reste du code (qui n'est pas le miens), où se trouvent les problèmes d'endianess, et de portabilité? Vos retours d'expérience à ce sujet m'intéressent.

    Merci et meilleures salutations

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  12. #12
    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 David.Schris
    Qu'est-ce qui n'est pas portable ?
    Bien lire la norme C99. C'est l'existence même de ce type qui n'est pas portable. Les types de tailles fixes doivent, certes, être implémentés, mais, à l'évidence, uniquement sur les plateformes qui les supportent. Dans les autres cas, il ne sont pas implémentés, d'où les problèmes de portablilité. Ca dépend de l'implémentation. Ce n'est donc pas portable.

  13. #13
    Membre émérite

    Profil pro
    Inscrit en
    Août 2003
    Messages
    878
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 878
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Bien lire la norme C99. C'est l'existence même de ce type qui n'est pas portable. Les types de tailles fixes doivent, certes, être implémentés, mais, à l'évidence, uniquement sur les plateformes qui les supportent. Dans les autres cas, il ne sont pas implémentés, d'où les problèmes de portablilité. Ca dépend de l'implémentation. Ce n'est donc pas portable.
    Ok. Je crois que je comprends ce que tu as voulu dire.
    Il est probable que nous ne comprenions pas le mot "portable" de la même façon. En caricaturant, pour toi "portable" veut dire "utilisable partout" alors que pour moi cela veut dire "utilisable ailleurs".

    Citation Envoyé par mujigka
    [...] Je peux effacer ce bout de code, [...]
    N'efface pas tout ce que tu écris (<- référence à un autre post) : cela peut aussi être utile, si erreur il y a, que les autres puissent les voir.

    Citation Envoyé par mujigka
    [...] Microsoft a même pris la décision de ne pas l'implanter du tout dans son propre compilateur. [...]
    Oui, ils estiment qu'on en a pas assez besoin (http://msdn.microsoft.com/chats/tran...o_022703.aspx).

  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 David.Schris
    Qu'est-ce qui n'est pas portable ?

    "Mon" "uint32_t", une fois compilé, il va bien se comporter de la même façon quelle que soit la plateforme, non ?
    Il me semblait d'ailleurs que c'était un peu le but de l'uint32_t : qu'il se comporte comme un entier non signé sur 32 bits quelle que soit la plateforme. Sinon : quel intérêt ?
    Suite à cette discussion, je vais ajouter une précision dans mon article. En effet, du code source qui ne peut pas compiler sur n'importe quelle machine n'est pas portable. Ca me paraissait évident, mais visiblement, il est bon de le rappeler.

  15. #15
    Membre émérite

    Profil pro
    Inscrit en
    Août 2003
    Messages
    878
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 878
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Suite à cette discussion, je vais ajouter une précision dans mon article. En effet, du code source qui ne peut pas compiler sur n'importe quelle machine n'est pas portable. Ca me paraissait évident, mais visiblement, il est bon de le rappeler.
    Modification vue...mais peut-être pas comprise...
    En tous cas, il y a toujours un truc qui me chagrine : tu commences par " Pour qu'un code source soit portable, il doit avant tout être compilable sur n'importe quelle plateforme. " mais dis, plus loin, " D'autre part, du code, bien que non normalisé, peut être portable (du moins sur un certain nombre de plateformes connues). "... Et là, c'est le drame : après avoir dit que la portabilité c'était soit tout blanc soit tout noir (cf. " n'importe quelle plateforme "), tu introduis la notion de "portabilité partielle/limitée" (cf. " un certain nombre de plateformes "). On en revient à la différence, déjà évoquée, entre "partout" et "ailleurs" (ou plutôt entre "partout" et "pas que sur une plateforme").

    Et au cas où cela ne serait pas clair : ce n'est pas pour le plaisir de chipoter ni de t'em....er que je reviens là-dessus

  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 David.Schris
    Et au cas où cela ne serait pas clair : ce n'est pas pour le plaisir de chipoter ni de t'em....er que je reviens là-dessus
    Tu as raison. Si ce n'est pas clair, ça demande à être amélioré.
    <...>
    Voilà, j'ai modifié. Effectivement, ça me parait plus clair comme ça...

    http://emmanuel-delahaye.developpez....s.htm#standard

    Remarques bienvenues.

Discussions similaires

  1. Travailler avec des gifs animés
    Par Commodore dans le forum Imagerie
    Réponses: 1
    Dernier message: 13/07/2006, 15h58
  2. Réponses: 8
    Dernier message: 09/03/2006, 17h48
  3. Travailler avec des hexadécimaux
    Par LEK dans le forum VB 6 et antérieur
    Réponses: 9
    Dernier message: 18/09/2005, 04h24
  4. Réponses: 3
    Dernier message: 25/01/2005, 11h27
  5. Travailler avec des bits
    Par Vulvulune dans le forum Langage
    Réponses: 5
    Dernier message: 02/03/2003, 19h09

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