2010-03-28 14 views
11

Scrivere un programma per determinare se un computer è big-endian o little-endian.Qualcuno può spiegare questa funzione di "endianità" per me?

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

Quindi ho la funzione di cui sopra. Non capisco davvero. ptr = (char *) & io, che credo significhi puntatore a un carattere all'indirizzo di dove sono seduto, quindi se un int è 4 byte, ad esempio ABCD, stiamo parlando di A o D quando chiami char * su quella? e perché?

Qualcuno potrebbe spiegarlo più dettagliatamente? Grazie.

In modo specifico, ptr = (char *) & i; quando lo lanci in char *, quale parte di & ricevo?

+9

sarebbe più comprensibile se si denominasse la funzione 'littleEndian()' poiché restituisce true se l'architettura è little endian. 'endianness() == true' non è molto informativo. –

+1

Potrebbe essere scritto in modo molto più conciso: 'bool little_endian (void) {static const int i = 1; return reinterpret_cast (i) == 1; } ' – GManNickG

risposta

33

Se si dispone di un'architettura little-endian, i sarà simile a questa in memoria (in esadecimale):

01 00 00 00 
^ 

Se si dispone di un big-endian architettura, i sarà simile a questa in memoria (in hex):

00 00 00 01 
^ 

il cast di char* ti dà un puntatore al primo byte del int (a cui ho accennato con un ^), quindi il valore a cui punta il char* sarà 01 se si è su un'architettura little-endian e 00 se si è su un'architettura big-endian.

Quando ritorni quel valore, 0 viene convertito in false e 1 viene convertito in true. Quindi, se hai un'architettura little-endian, questa funzione restituirà true e se hai un'architettura big-endian, restituirà false.

1

Questo sta usando il tipo puning per accedere a un numero intero come una matrice di caratteri. Se la macchina è big endian, questo sarà il byte principale e avrà un valore pari a zero, ma se la macchina è little endian, sarà il byte minore, che avrà un valore di uno. (Invece di accedere a i come un singolo numero intero, è possibile accedere alla stessa memoria come una matrice di quattro caratteri).

0

Se il *((char*)&i) è il byte A o il byte D arriva al cuore di endianness. Su un sistema little endian, il numero intero 0x41424344 sarà disposto in memoria come: 0x44 43 42 41 (il byte meno significativo prima, in ASCII, questo è "DCBA"). Su un sistema big endian, sarà strutturato come: 0x41 42 43 44. Un puntatore a questo intero conterrà l'indirizzo del primo byte. Considerando il puntatore come puntatore intero, ottieni l'intero intero. Considera il puntatore come un puntatore char e ottieni il primo byte, poiché è la dimensione di un char.

0

Certo,

Diamo un'occhiata

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

Se la macchina è little endian, quindi i dati saranno in * ptr sarà 0000 0001.

Se la macchina è Big Endian, quindi sarà invertita dei dati, vale a dire, sarò

i = 0000 0000 0000 0001 0000 0000 0000 0000 

Così * PTR terrò 0x0

Infine, il ritorno * ptr è equivalente a

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

else //big endian 
2

Se ptr punti al byte A o D dipende dal endianness della macchina. ptr punta a quel byte del numero intero che corrisponde all'indirizzo più basso (gli altri byte saranno a ptr+1, ...).

Su un grande-endian macchina più significativo byte del numero intero (che è 0x00) dovrà essere conservato a questo indirizzo più basso, per cui la funzione restituirà zero.

Su una macchina litte-endian è il contrario, il almeno significativo byte del numero intero (0x01) sarà memorizzato all'indirizzo più basso, per cui la funzione restituirà uno in questo caso.

0

Assumere int è 4 byte (in C potrebbe non essere). Questo presupposto è solo per semplificare l'esempio ...

È possibile esaminare ciascuno di questi 4 byte singolarmente.

char è un byte, quindi sta esaminando il primo byte di un buffer da 4 byte.

Se il primo byte non è 0, questo indica se il bit più basso è contenuto nel primo byte.

ho casualmente scelto il numero 42 per evitare la confusione di qualsiasi significato speciale nel valore 1.

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

Ripartizione:

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); 

Se è vero firstByteOf4Is42 avete little-endian. Se lastByteOf4Is42 è true, hai big-endian.

Problemi correlati