2010-03-28 14 views
11

Escribe un programa para determinar si una computadora es big-endian o little-endian.¿Alguien puede explicarme esta función de "endian-ness"?

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

Así que tengo la función anterior. Realmente no lo entiendo ptr = (char *) & i, que creo que significa un puntero a un carácter en la dirección de donde estoy sentado, así que si un int es de 4 bytes, di ABCD, ¿estamos hablando de A o D cuando llamas a char *? ¿ese? ¿y por qué?

¿Alguien podría explicar esto con más detalle? Gracias.

Específicamente, ptr = (char *) & i; cuando lo lanzas a char *, ¿qué parte de & obtengo?

+9

sería más comprensible si nombrara la función 'littleEndian()' ya que devuelve true si la arquitectura es little endian. 'endianness() == true' no es muy informativo. –

+1

Se podría escribir mucho más concisamente: 'bool little_endian (void) {static const int i = 1; return reinterpret_cast (i) == 1; } ' – GManNickG

Respuesta

33

Si usted tiene una arquitectura ascendente hacia la izquierda, i se verá así en la memoria (en hexadecimal):

01 00 00 00 
^ 

Si usted tiene una arquitectura big-endian, i se verá así en la memoria (en hexadecimal):

00 00 00 01 
^ 

el reparto de char* le da un puntero al primer byte de la int (a la que he señalado con un ^), por lo que el valor apuntado por el char* será 01 si está en una arquitectura little-endian y 00 si está en una arquitectura big-endian.

vez que regrese ese valor, se convierte en 0false y 1 se convierte en true. Por lo tanto, si tiene una arquitectura little-endian, esta función devolverá true y si tiene una arquitectura big-endian, devolverá false.

1

Esto está utilizando el tipo de juego de palabras para acceder a un número entero como una matriz de caracteres. Si la máquina es big endian, este será el byte principal, y tendrá un valor de cero, pero si la máquina es poco endian, será el byte menor, que tendrá un valor de uno. (En lugar de acceder al i como un entero único, se accede a la misma memoria como una matriz de cuatro caracteres).

0

Si *((char*)&i) es el byte A o el byte D llega al corazón del endianness. En un pequeño sistema endian, el número entero 0x41424344 se colocará en la memoria como: 0x44 43 42 41 (el byte menos significativo primero; en ASCII, esto es "DCBA"). En un sistema endian grande, se distribuirá como: 0x41 42 43 44. Un puntero a este número entero mantendrá la dirección del primer byte. Teniendo en cuenta el puntero como un puntero entero, y obtienes el entero entero. Considere el puntero como un puntero de char, y obtiene el primer byte, ya que es del tamaño de un char.

0

Claro,

permite echar un vistazo

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

Si la máquina es Little Endian, a continuación, los datos estarán en * ptr será 0000 0001.

Si la máquina está Big Endian, a continuación, se invertirá de datos, es decir, voy a ser

i = 0000 0000 0000 0001 0000 0000 0000 0000 

Así * ptr sostendré 0x0

Por último, el retorno * ptr es equivalente a

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

else //big endian 
2

Si ptr apunta a byte A o D depende de la endianidad de la máquina. ptr apunta a ese byte del entero que está en la dirección más baja (los otros bytes estarían en ptr+1, ...).

En una máquina-big endian la más byte significativo del número entero (que es 0x00) se almacenarán en esta dirección más baja, por lo que la función devolverá cero.

En una máquina litte-endian es lo contrario, la menos byte significativa del número entero (0x01) será almacenado en la dirección más baja, por lo que la función devolverá uno en este caso.

0

Supongamos que int es de 4 bytes (en C puede no serlo). Esta suposición es solo para simplificar el ejemplo ...

Puede ver cada uno de estos 4 bytes individualmente.

char es un byte, por lo que está mirando el primer byte de un búfer de 4 bytes.

Si el primer byte es distinto de 0, eso indica si el bit más bajo está contenido en el primer byte.

Me eligieron al azar el número 42 para evitar la confusión de cualquier significado especial en el valor 1.

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

Desglose:

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 es cierto que tiene ascendente hacia la izquierda. Si lastByteOf4Is42 es verdadero, entonces tienes big-endian.

Cuestiones relacionadas