2010-03-28 7 views
11

Écrivez un programme pour déterminer si un ordinateur est big-endian ou little-endian.Quelqu'un peut-il expliquer cette fonction "endian-ness" pour moi?

bool endianness() { 
    int i = 1; 
    char *ptr; 
    ptr = (char*) &i; 
    return (*ptr); 
} 

J'ai donc la fonction ci-dessus. Je ne comprends pas vraiment. ptr = (char *) & je, qui je pense signifie un pointeur vers un caractère à l'adresse de où je suis assis, donc si un int est de 4 octets, disons ABCD, parlons-nous de A ou D lorsque vous appelez char * on cette? et pourquoi?

Quelqu'un pourrait-il expliquer cela plus en détail? Merci.

Donc spécifiquement, ptr = (char *) & i; quand vous le lancez en char *, quelle partie de & puis-je obtenir?

+9

il serait plus compréhensible si vous avez nommé la fonction 'littleEndian()' car elle renvoie vrai si l'architecture est peu endian. 'endianness() == true' n'est pas très instructif. –

+1

Il pourrait être écrit beaucoup plus concis: 'bool little_endian (void) {statique const int i = 1; return reinterpret_cast (i) == 1; } ' – GManNickG

Répondre

33

Si vous avez une architecture peu endian, i ressemblera à ceci en mémoire (en hexadécimal):

01 00 00 00 
^ 

Si vous avez une architecture big-endian, i ressemblera à ceci en mémoire (en hex):

00 00 00 01 
^ 

le casting de char* vous donne un pointeur sur le premier octet du int (à laquelle je l'ai fait avec un ^), de sorte que la valeur pointée par le char* sera 01 si vous êtes sur une architecture little-endian et 00 si vous êtes sur une architecture big-endian. Lorsque vous renvoyez cette valeur, 0 est converti en false et 1 est converti en true.Donc, si vous avez une architecture little-endian, cette fonction renverra true et si vous avez une architecture big-endian, elle renverra false.

1

Ceci utilise type punning pour accéder à un nombre entier en tant que tableau de caractères. Si la machine est grosse, ce sera l'octet majeur, et aura une valeur de zéro, mais si la machine est peu endian, ce sera l'octet mineur, qui aura une valeur de un. (Au lieu d'accéder à i en tant qu'entier unique, la même mémoire est accessible sous la forme d'un tableau de quatre caractères).

0

Si *((char*)&i) est l'octet A ou l'octet D arrive au coeur de l'endianness. Sur un petit système endian, l'entier 0x41424344 sera mis en mémoire en tant que: 0x44 43 42 41 (octet le moins significatif d'abord, en ASCII, c'est "DCBA"). Sur un grand système endian, il sera disposé comme suit: 0x41 42 43 44. Un pointeur vers cet entier contiendra l'adresse du premier octet. Considérant le pointeur comme un pointeur entier, et vous obtenez l'entier entier. Considérez le pointeur comme un pointeur char, et vous obtenez le premier octet, puisque c'est la taille d'un char.

0

Bien sûr,

permet de jeter un coup d'oeil

bool endianness() { 
    int i = 1; //This is 0x1: 
    char *ptr; 
    ptr = (char*) &i; //pointer to 0001 
    return (*ptr); 
} 

Si la machine est peu endian, les données seront en * ptr sera 0000 0001.

Si la machine est Big Endian, les données seront inversées, à savoir, je serai

i = 0000 0000 0000 0001 0000 0000 0000 0000 

So * PTR tiendra 0x0

Enfin, le retour * ptr est équivalent à

if (*ptr = 0x1) //little endian 

else //big endian 
2

Si ptr pointe sur l'octet A ou D dépend de l'endianness de la machine. ptr indique l'octet de l'entier qui se trouve à l'adresse la plus basse (les autres octets seraient ptr+1, ...).

Sur une machine big-endian le plus octet significatif de l'entier (qui est 0x00) seront stockées à cette adresse la plus basse, de sorte que la fonction retourne zéro.

Sur une machine litte-boutiste, il est à l'opposé, le moins octet de poids faible de l'entier (0x01) est stocké à l'adresse la plus basse, de sorte que la fonction retourne une dans ce cas.

0

Supposons que int est égal à 4 octets (en C, il peut ne pas l'être). Cette hypothèse est juste pour simplifier l'exemple ...

Vous pouvez regarder chacun de ces 4 octets individuellement.

char est un octet, donc il regarde le premier octet d'un tampon de 4 octets.

Si le premier octet est non 0 alors cela vous indique si le bit le plus bas est contenu dans le premier octet.

J'ai choisi au hasard le numéro 42 pour éviter toute confusion de toute signification particulière dans la valeur 1.

int num = 42; 
if(*(char *)&num == 42) 
{ 
     printf("\nLittle-Endian\n"); 
} 
else 
{ 
     printf("Big-Endian\n"); 
} 

Répartition:

int num = 42; 
//memory of the 4 bytes is either: (where each byte is 0 to 255) 
//1) 0 0 0 42 
//2) 42 0 0 0 

char*p = #/*Cast the int pointer to a char pointer, pointing to the first byte*/ 
bool firstByteOf4Is42 = *p == 42;/*Checks to make sure the first byte is 1.*/ 

//Advance to the 2nd byte 
++p; 
assert(*p == 0); 

//Advance to the 3rd byte 
++p; 
assert(*p == 0); 

//Advance to the 4th byte 
++p; 
bool lastByteOf4Is42 = *p == 42; 
assert(firstByteOf4Is42 == !lastByteOf4Is42); 

Si firstByteOf4Is42 est vrai que vous avez peu endian. Si lastByteOf4Is42 est vrai alors vous avez big-endian.