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

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  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 : 41
    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 ?

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