2009-07-21 5 views
2

J'étudie big and little-endianness.Pour comprendre un code C sur l'endianness

1. Quel est l'objet de | \ dans le code suivant?

... 

#elif defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN) 

    #define htons(A) ((((uint16_t)(A) & 0xff00) >> 8) | \ 
        (((uint16_t)(A) & 0x00ff) << 8)) 
... 

2. Quel est le but de (A) dans le code?

+0

Merci pour vos réponses! –

+1

Vous n'avez pas besoin de masque & 0xff00 ou & 0x00ff - dans le premier cas, les 8 bits inférieurs sont masqués car ils se décalent vers le bas. Dans le second cas, les bits débordent et sont perdus. (uint16_t) (((uint16_t) (A) >> 8) | ((uint16_t) (A) << 8))) aurait le même résultat –

+0

@ Tom Leys est en désaccord sur le 2ème cas. '(((uint16_t) (A)) << 8))'. 'A' est converti en' uint16_t' en conservant ses 16 LSbits. Ensuite, on pense aux promotions entières habituelles qui peuvent être à un int de 32 bits par exemple. Alors cette valeur est décalée 8. Peu probable ce que l'OP désirait. – chux

Répondre

16

Le '|' est l'opérateur OU bit à bit. Il combine essentiellement les valeurs. Le 'A' est le paramètre du #define htons. Il est entouré de parenthèses, de sorte que les expressions ne vont pas perturber le programmeur ou le compilateur. Le '\' continue la macro sur la ligne suivante. (Une macro se termine généralement à la fin de la ligne.)

Cette macro prend la valeur de 16 bits dans A et masque les 8 premiers bits. Il prend alors cette valeur et la déplace sur 8 bits. Cela signifie que les 8 bits supérieurs sont maintenant en bas de la valeur 16 bits. Il masque ensuite les 8 premiers bits de la valeur d'origine dans A et décale les 8 bits restants. Cela signifie que les 8 derniers bits sont maintenant en haut. Enfin, il recombine les deux valeurs en une seule valeur.

Le résultat final est que les octets supérieur et inférieur ont été remplacés.

3

| exécute un "OR" bit à bit sur deux entiers \ est un caractère d'échappement qui permet à un #define de cotniner sur la ligne suivante

+0

Je suis arrivé à la question 30 secondes trop tard, il semble. : P – Victor

4

Ce code n'est rien d'autre que des macros de préprocesseur C standard. Le | est l'opérateur OU bit à bit. Le \ échappe à la nouvelle ligne de sorte que le #define peut continuer à la ligne suivante. Le (A) est un paramètre pour la macro.

2

C'est une macro, elle sera développée quand vous l'utiliserez.

Si vous effectuez par ex. utiliser ("call") la macro comme

uint16_t i = htons(0x1234); 

Il étendra à:

uint16_t i = ((((uint16_t)(0x1234) & 0xff00) >> 8) |(((uint16_t)(0x1234) & 0x00ff) << 8)); 

Ce n'est pas que, contrairement à une variable dans une fonction, par exemple

uint16_t htons(uint16_t A) 
{ 
    return (A & 0xff00) >> 8) | (A & 0x00ff) << 8); 
} 
+0

De bons exemples! –

+1

Avez-vous deux ')' trop dans le dernier code à '8)'? –

+2

Pour l'une des révélations les plus importantes pour un programmeur C/C++, considérez ce que 'uint16_t i = 0x1233; uint16_t j = htons (i ++); 'aboutit à. –

Questions connexes