2016-02-29 1 views
0

Je viens de faire une petite expérience sur le Raspberry Pi je travaille avec le code suivant:C petit boutiste mais produit un gros résultat endian?

//tutorialspoint.com/unix_sockets/network_byte_orders.htm 

#include <stdio.h> 

int main(int argc, char **argv) { 

    union { 
     short s; 
     char c[sizeof(short)]; 
    }un; 

    un.s = 0x0102; 

    if (sizeof(short) == 2) { 
     if (un.c[0] == 1 && un.c[1] == 2) 
     printf("big-endian\n"); 

     else if (un.c[0] == 2 && un.c[1] == 1) 
     printf("little-endian\n"); 

     else 
     printf("unknown\n"); 
    } 
    else { 
     printf("sizeof(short) = %d\n", sizeof(short)); 
    } 

    exit(0); 
} 

Le résultat que je suis arrivé était peu endian.

Maintenant, quand je convertir un nombre entier à l'octet tableau, le résultat qui est sorti est en big endian

unsigned char c[4]; 
int num = 170; // suppose to give 0000 0000 0000 00AA 
memcpy(c, (char*)&num, sizeof(int)); 
printf("c[0] = %04x \n", c[0]); 
printf("c[1] = %04x \n", c[1]); 
printf("c[2] = %04x \n", c[2]); 
printf("c[3] = %04x \n", c[3]); 
memcpy((char *)&num, c, sizeof(int)); 
printf("%d\n", ntohl((long)num)); 

sortie:

c [0] = 00aa

c [ 1] = 0000

c [2] = 0000

c [3] = 0000

-1442840576

je devais faire un changement pour l'obtenir pour devenir peu endian

//c[0] = (num >> 24) & 0xFF; 
//c[1] = (num >> 16) & 0xFF; 
//c[2] = (num >> 8) & 0xFF; 
//c[3] = num & 0xFF; 

Maintenant, je suis confus si mon pi framboise est peu endian ou big endian? En outre, je vais passer ces données à travers un socket, je dois donc m'assurer qu'il est dans l'ordre des octets du réseau ou est-ce correct tant que je standardisé quel endian je vais utiliser à travers tous les appareils avec lesquels j'essaie de communiquer?

PS. De plus, si j'ai besoin de convertir manuellement tous les entiers dans un tableau entier de petit endian à big endian, quelle est l'approche que je devrais faire? La plupart des solutions que je trouve en ligne ne font que convertir un entier et non un tableau d'entiers.

+1

La façon dont le code «0000 0000 0000 00AA» est écrit pour les humains qui lisent de gauche à droite va stocker «AA» dans l'octet inférieur, qui dans le petit boutiste vous a donné exactement ce que vous avez obtenu. –

+0

Pourquoi ne pas utiliser la même valeur 0x0102 pour les deux tests? vous verrez que vous obtenez le même résultat: 02 est le premier. –

+0

Utilisez une sérialisation appropriée avec des décentrements/masques.Ne comptez pas sur un comportement défini par l'implémentation ou potentiellement indéfini. Avec un bon compilateur, il n'y aura pas ou juste une pénalité de vitesse marginale. – Olaf

Répondre

4

Il est little-endian dans les deux cas.

Dans votre premier cas, l'octet le moins significatif est 2 et correspond à c [0] - little-endian. Dans votre second cas, l'octet le moins significatif est 170 (tous les autres sont nuls) et correspond à c [0] - little-endian.

Si vous copiez des données sur un socket, vous devez simplement vous assurer que le format de données est cohérent. Peu importe ce que c'est.

Pour copier un tableau de données, faites simplement la même chose qu'un seul élément, mais répétez-le.

1
int num = 170; // suppose to give 0000 0000 0000 00AA 

Non, il est censé vous donner AA, 00, 00, 00 (ou AA, 00, 00, 00, 00, 00, 00, 00 si int est de 64 bits).
Dans une mise en page little-endian, l'octet le moins significatif est stocké à l'adresse la plus faible. L'octet le moins significatif de 0x000000AA (170) est 0xAA.

+0

Ah ok je l'ai eu! Merci :) –