/ / Duży / Mały detektor endianów (C ++) [duplikat] - c ++, char, byte

Detektor Big / Little Endian (C ++) [duplikat] - c ++, char, byte

Możliwe duplikaty:
Programowe wykrywanie endianizmu w programie C ++

Pracuję nad projektem w C ++, który wymaga, aby wiedzieć, czy system to duży endian, czy mały endian.

Wymyśliłem jakiś kod, który ja myśleć udało się to wykryć! Jednak po raz pierwszy tak naprawdę programuję i chciałbym wiedzieć, czy to naprawdę zadziała:

int fourbytesint = 0;//Initialize four bytes
((char*)&fourbytesint)[0] = 1;//Get the first byte of our four bytes
//(Pretend the int is an array of 4 bytes, get the first byte)

//Depending upon the endian, this will be a reasonably small number, or an unreasonably large number
if (fourbytesint > 1000)
{
cout << "Big endian!" << endl;
}
else
{
cout << "Little Endian!" << endl;
}

Ponadto instruktor nauczył mnie, że char, w c ++ może być używany do przechowywania bajtów. Jestem trochę ostrożny, jak wiem w językach takich jak Java, char zwykle przechowuje dwa bajty znaków Unicode.

Czy mam rację, używając znaku char jako bajtu w powyższym przykładzie?

Odpowiedzi:

2 dla odpowiedzi № 1

Tak, twoja metoda wykrywania działa. (chociaż możesz być w stanie napisać kod w sposób niezależny od Endian, na przykład używając htonl() jak sugeruje Brian Roach. Spowoduje to również, że Twój kod będzie działał, nawet jeśli big endian i little endian nie są jedynymi opcjami.)

Tak, char w C ++ to jeden bajt. Według definicji sizeof (char) == 1

Edytować: jak wskazano w komentarzach, możliwe jest, że sizeof (char) == sizeof (int). Twój kod wykryłby to jako duży endian. Ale koncepcja endianness nie ma sensu, gdy miejsce na typ nie robi t obejmuje wiele adresowalnych lokalizacji. To znaczy, ponieważ „big endian” oznacza, że ​​„podjednostki” int są uporządkowane w taki sposób, że bardziej znaczące pojawiają się przed mniej znaczącymi, nie ma sensu używać tego terminu dla czegoś który ma tylko jedną „podjednostkę”. Mimo to możesz napisać kod dla dowolnej gałęzi, tak aby obsługiwał ten przypadek, a wtedy nie będzie to miało znaczenia.


3 dla odpowiedzi № 2

Najprostszym sposobem IMHO jest użycie htonl() funkcjonować.

Na dużej maszynie Endian htonl() będzie opcją, a twoja wartość nie zmieni się.


2 dla odpowiedzi nr 3

W systemie Mac OS X kod będzie działał w celu wykrywania małych systemów endian lub big endian.

Historycznie istniała inna kategoria -systemy „mieszane endian”, w których bajty są w dziwnej kolejności (nie 4321 lub 1234, ale coś dziwniejszego jak 2143 lub coś takiego). W takim przypadku Twój kod może tego nie wykryć - fourbytesint może skończyć 256. Najlepiej używać kontroli równości dla takiego kodu. Ponieważ jednak OS X nie działa na mieszanych systemach endianowych, nie jest to praktyczny problem dla twoich celów.

Ponadto w systemie OS X lepiej byłoby użyć htonl (od <arpa/inet.h>) dla tego wykrywania. htonl w wielu systemach uniksowych można zoptymalizować w czasie kompilacji, usuwając narzut związany z czasem wykonywania z takiego testu.


2 dla odpowiedzi № 4

Zrobiłbym następujące, aby sprawdzić endianness:

bool isLittleEndian()
{
unsigned num = 0xABCD;

return *((unsigned char*)&num) == 0xCD;
}

Jak powiedzieli inni, sizeof(char) równa się 1.

Cały standard C ++ mówi o unsigned int jest to, że jest w stanie utrzymać wartości od 0 do 0xFFFF (w zasadzie co najmniej 2 bajty), dlatego użyłem tej wartości 0xABCD w przeciwieństwie do tego, który „używałby 4 bajtów (równie dobrze mógł użyć 0xCD).

I unsigned char zamiast signed jeden jest lepszy do reprezentowania bajtów, ponieważ najprawdopodobniej potrzebujesz surowego, unsigned wartość bajtu.


1 dla odpowiedzi nr 5

na odwrót może być łatwiej. utwórz liczbę całkowitą, ustaw ją na wartość 1., a następnie podziel ją na bajty za pomocą wskaźnika bajtów i sprawdź, czy jest to pierwszy czy ostatni bajt o wartości 1 (pozostałe będą miały wartość 0).


1 dla odpowiedzi № 6

Twój kod jest poprawny, ale jest zbyt skomplikowany.
Jest to prostsze i łatwiejsze do odczytania.

short var = 0x1;
char * byte = (char *) &var;
if(byte[0] > 0){
cout << "Little Endian";
}
else{
cout << "Big Endian";
}