2010-03-28 11 views
11

Schreiben Sie ein Programm, um festzustellen, ob ein Computer Big-Endian oder Little-Endian ist.Kann jemand diese "Endian-Ness" -Funktion für mich erklären?

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

So habe ich die obige Funktion. Ich verstehe es nicht wirklich. ptr = (char *) & ich, was ich denke, bedeutet einen Zeiger auf ein Zeichen an Adresse von wo ich sitze, also wenn ein int ist 4 Bytes, sagen ABCD, sprechen wir über A oder D, wenn Sie char * on aufrufen Das? und warum?

Würde jemand bitte dies genauer erklären? Vielen Dank.

Also speziell, ptr = (char *) & i; Wenn Sie es in char * umwandeln, welchen Teil von & erhalte ich?

+9

Es wäre verständlicher, wenn Sie die Funktion 'littleEndian()' nennen würden, da sie true zurückgibt, wenn die Architektur Little Endian ist. 'endianness() == true' ist nicht sehr informativ. –

+1

Es könnte viel prägnanter geschrieben werden: 'bool little_endian (void) {statisch const int i = 1; return reinterpret_cast (i) == 1; } ' – GManNickG

Antwort

33

Wenn Sie ein Little-Endian-Architektur haben, werden i wie folgt aussehen im Speicher (in hex):

01 00 00 00 
^ 

Wenn Sie eine Big-Endian-Architektur haben, i wie dies in Erinnerung aussehen wird (in hex):

00 00 00 01 
^ 

die Besetzung zu char* gibt Ihnen einen Zeiger auf das erste Byte des int (auf die ich mit einem ^ hingewiesen haben), so dass der Wert der char* zeigteseinWenn Sie auf einer Little-Endian-Architektur sind und 00 wenn Sie auf einer Big-Endian-Architektur sind.

Wenn Sie diesen Wert zurückgibt, wird 0-false umgewandelt und 1 zu true umgewandelt wird. Wenn Sie also eine Little-Endian-Architektur haben, gibt diese Funktion true zurück und wenn Sie eine Big-Endian-Architektur haben, wird false zurückgegeben.

1

Dies ist Typ punning verwenden, um eine ganze Zahl als ein Array von Zeichen zuzugreifen. Wenn die Maschine Big Endian ist, wird dies das Haupt-Byte sein und wird einen Wert von Null haben, aber wenn die Maschine Little Endian ist, wird es das Neben-Byte sein, das einen Wert von Eins haben wird. (Anstatt auf i als eine einzelne Ganzzahl zuzugreifen, wird auf denselben Speicher wie ein Array von vier Zeichen zugegriffen).

0

Ob *((char*)&i) ist Byte A oder Byte D gelangt zum Herzen der Endianess. Auf einem kleinen Endian-System wird die Ganzzahl 0x41424344 im Speicher wie folgt angeordnet: 0x44 43 42 41 (niedrigstwertiges Byte zuerst; in ASCII ist dies "DCBA"). Auf einem Big-Endian-System wird es wie folgt angeordnet: 0x41 42 43 44. Ein Zeiger auf diese Ganzzahl enthält die Adresse des ersten Bytes. Betrachten Sie den Zeiger als Integer-Zeiger, und Sie erhalten die ganze Zahl. Betrachten Sie den Zeiger als Char-Zeiger, und Sie erhalten das erste Byte, da dies die Größe eines Zeichens ist.

0

Sicher,

Werfen wir einen Blick

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

Wenn die Maschine Little Endian ist, dann werden die Daten in * ptr wird 0000 0001 sein.

Wenn die Maschine Big Endian wird, dann werden die Daten, dh invertiert werden, i

i = 0000 0000 0000 0001 0000 0000 0000 0000 

sein wird, also * wird ptr halten 0x0

Schließlich ist die Rückkehr * ptr zu

gleichwertig
2

Wenn ptr zeigt auf Byte A oder D hängt von der Endianess der Maschine ab. ptr zeigt auf das Byte der Ganzzahl, die die niedrigste Adresse hat (die anderen Bytes wären ptr+1, ...).

Auf einer Big-Endian-Maschine des meisten signifikante Bytes der ganzen Zahl (die 0x00 ist) wird an dieser niedrigsten Adresse gespeichert werden, so wird die Funktion Null zurück.

Auf einer litte-Endian-Maschine ist es genau umgekehrt, der dest niederwertige Byte der ganzen Zahl (0x01) wird bei der niedrigsten Adresse gespeichert werden, so dass die Funktion eines in diesem Fall angezeigt werden kann.

0

Angenommen int ist 4 Bytes (in C kann es nicht sein). Diese Annahme dient lediglich zur Vereinfachung des Beispiels ...

Sie können jedes dieser 4 Bytes einzeln betrachten.

char ist ein Byte, also sieht man sich das erste Byte eines 4-Byte-Puffers an.

Wenn das erste Byte nicht 0 ist, dann sagt das, ob das niedrigste Bit im ersten Byte enthalten ist.

wählte ich zufällig die Nummer 42 Verwirrung eine besondere Bedeutung im Wert 1.

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

Aufteilung zu vermeiden:

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

Wenn firstByteOf4Is42 wahr ist, haben Sie Little-Endian. Wenn lastByteOf4Is42 wahr ist, dann haben Sie Big-Endian.