OVH Cloud OVH Cloud

Travailler avec des bytes en C

48 réponses
Avatar
simon.bree
Bonjour,

J'ai un buffer de byte en C.

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

Estg-ce la m=EAme chose en C? Et si oui, pourriez-vous m'expliquer cette=20
syntaxe?

Merci d'avance,
Simon

10 réponses

1 2 3 4 5
Avatar
simon.bree
Merci Eric pour les précisions sur les char, byte et octet.

Moi, je défini mon buffer ainsi :
uint8_t buf[1024];

Est-ce donc correct, et
- si non, comment je dois le déclaré (car buf[1024]?) ?
- si oui, est-ce bien utile que j'utilise le masque 0xff (puisque
uint8_t est un octet) ?

Simon
Avatar
Eric Levenez
Le 27/01/07 16:34, dans , « Pierre
Maurette » a écrit :


J'aurais pas dû dire logique. Content ?


"Content" n'est pas le fond du problème.


Ce que j'aime, ce sont les personnes qui répondent aux questions des
participants de façon constructive et qui ne se contentent pas d'arriver
après en jouant au prof.

Il y a quand même un souci à
confondre un opérateur logique et un opérateur arithmétique (bitwise).


Tu sais très bien que c'est juste une erreur typographique. Et oui il y a un
"souci" sur ta réponse.

--
Éric Lévénez -- <http://www.levenez.com/>
Unix is not only an OS, it's a way of life.


Avatar
Eric Levenez
Le 27/01/07 17:42, dans
,
«  » a écrit :

Moi, je défini mon buffer ainsi :
uint8_t buf[1024];


C'est un tableau d'entier faisant tous exactement 8 bits.

Est-ce donc correct, et
- si non, comment je dois le déclaré (car buf[1024]?) ?


C'est correct.

Il faut juste savoir que le type "uint8_t" n'est pas disponible sur toutes
les architectures. Il faut en effet une architecture capable d'adresser des
octets de façon unitaire, ce qui généralement le cas il est vrai.

- si oui, est-ce bien utile que j'utilise le masque 0xff (puisque
uint8_t est un octet) ?


Un (buf[x] & 0xff) n'est pas utile en effet pour tronquer le nombre à 8
bits.

--
Éric Lévénez -- <http://www.levenez.com/>
Unix is not only an OS, it's a way of life.

Avatar
Xavier Roche
Moi, je défini mon buffer ainsi :
uint8_t buf[1024];


Moi j'aurais mis
unsigned char buf[1024];

C'est le plus portable, le plus universel.

Parce que bon, les architectures où sizeof(char) != 1, on doit en voir
une fois dans sa vie, quand on a atteint l'âge de la retraite.

Juste mes 15c¤.

Avatar
Pascal Bourguignon
Xavier Roche writes:

(buffer[0] & 0xff) | ((buffer[1] & 0xff) << 8) | ((buffer[2] & 0xff)
<< 16) | (buffer[3] << 24)


Déja, il faut savoir que cette représentation est en little endian (le
"petit bout", càd les octets de poids les plus faibles, sont en
premier) et ne sera pas toujours compatible selon les cas avec la
plate-forme voulue. Disons que, dans des représentations réseau, c'est
effectivement le plus courant.

Sinon le "& 0xff" qui masque les 8 premiers bits ne sert pas à grand
chose (buffer[n] est déja sur 8 bits),


Ça ce n'est pas évident. Ce n'est vrai que si CHAR_BIT==8 (#include
<limits.h>). Sur une machine à mot de 36 bits, on pourrait trés bien
avoir CHAR_BIT=9 et alors, le &0xff serait trés utile.


par contre un cast de chaque
octet en uint avant le décalage me parait sécurisant, dans la mesure
où le type résultant d'un (unsigned char)<<n n'est pas à priori
forcément un int..

J'aurais plutôt écrit:

unsigned int foo = ( (unsigned int) buffer[0] )
| ( ( (unsigned int) buffer[1] ) << 8 )
| ( ( (unsigned int) buffer[2] ) << 16 )
| ( ( (unsigned int) buffer[3] ) << 24 );


Oui, en ajoutant &0xff.

--
__Pascal Bourguignon__ http://www.informatimago.com/
Grace personified,
I leap into the window.
I meant to do that.


Avatar
Pierre Maurette
Moi, je défini mon buffer ainsi :
uint8_t buf[1024];


Moi j'aurais mis
unsigned char buf[1024];

C'est le plus portable, le plus universel.

Parce que bon, les architectures où sizeof(char) != 1, on doit en voir une
fois dans sa vie, quand on a atteint l'âge de la retraite.


Vous vous tirez sur l'élastique ?

--
Pierre Maurette


Avatar
Eric Levenez
Le 27/01/07 22:54, dans <epghne$uri$, « Xavier Roche »
a écrit :

Moi, je défini mon buffer ainsi :
uint8_t buf[1024];


Moi j'aurais mis
unsigned char buf[1024];

C'est le plus portable, le plus universel.


Plus universel oui, plus portable pas évident.

uint8_t est justement introduit dans la norme pour définir un entier non
signé 8 bits. Le "unsigned char" n'est pas forcément 8 bits.

Parce que bon, les architectures où sizeof(char) != 1, on doit en voir
une fois dans sa vie, quand on a atteint l'âge de la retraite.


Tu rigoles je pense. Je bosse dans l'embarqué sur DSP 32 bits et les char
sont 32 bits. Et sizeof(char) vaut toujours 1 par définition.

--
Éric Lévénez -- <http://www.levenez.com/>
Unix is not only an OS, it's a way of life.


Avatar
Xavier Roche
uint8_t est justement introduit dans la norme pour définir un entier non
signé 8 bits. Le "unsigned char" n'est pas forcément 8 bits.


Mouarf. Bon, oui, d'accord. Ce que je voulais dire, c'est que pour un
débutant, sizeof(char) == 1.

C'est comme sizeof(void*) != sizeof(void (*)(void)): oui, ça existe.
Mais pour un débutant, il vaut mieux l'oublier, cela ne sert à rien de
complexifier à l'extrème les choses.

Et non, les programmeurs DSP ne courent pas les rues.

Avatar
Pascal Bourguignon
Xavier Roche writes:

uint8_t est justement introduit dans la norme pour définir un entier non
signé 8 bits. Le "unsigned char" n'est pas forcément 8 bits.


Mouarf. Bon, oui, d'accord. Ce que je voulais dire, c'est que pour un
débutant, sizeof(char) == 1.


Même pour un spécialiste. Pour tout le monde, sizeof(char)==1. C'est
la définition même de sizeof de donner 1 pour char.


C'est comme sizeof(void*) != sizeof(void (*)(void)): oui, ça
existe. Mais pour un débutant, il vaut mieux l'oublier, cela ne sert à
rien de complexifier à l'extrème les choses.

Et non, les programmeurs DSP ne courent pas les rues.


Il y a pourtant beaucoup plus de DSP dans la nature que de
microprocesseurs dans des PC.


--
__Pascal Bourguignon__ http://www.informatimago.com/

Nobody can fix the economy. Nobody can be trusted with their finger
on the button. Nobody's perfect. VOTE FOR NOBODY.


Avatar
Xavier Roche
Il y a pourtant beaucoup plus de DSP dans la nature que de
microprocesseurs dans des PC.


Mais il y a beaucoup, beaucpup plus de lignes de codes écrites pour ces
derniers.

1 2 3 4 5