Может ли кто-нибудь объяснить эту функцию "endian-ness" для меня?

Напишите программу, чтобы определить, является ли компьютер широкоэкранным или мало-endian.

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

Итак, у меня есть вышеуказанная функция. Я действительно не понимаю. ptr = (char *) & i, который, я думаю, означает указатель на символ по адресу, где сидит i, поэтому, если int составляет 4 байта, например ABCD, мы говорим об A или D, когда вы вызываете char * на этом? и почему?

Может кто-нибудь объяснить это более подробно? Спасибо.

Так конкретно, ptr = (char *) & i; когда вы набрасываете его на char *, какую часть & я получаю?

Ответ 1

Если у вас есть архитектура little-endian, i будет выглядеть так в памяти (в шестнадцатеричном формате):

01 00 00 00
^

Если у вас есть архитектура большого конца, i будет выглядеть так в памяти (в шестнадцатеричном формате):

00 00 00 01
^

Приведение в char* дает указатель на первый байт int (на который я указал с помощью ^), поэтому значение, на которое указывает char*, будет 01, если вы находятся на архитектуре little-endian и 00, если вы находитесь в архитектуре большого конца.

Когда вы вернете это значение, 0 преобразуется в false, а 1 преобразуется в true. Итак, если у вас есть архитектура little-endian, эта функция вернет true, и если у вас есть архитектура с большим концом, она вернет false.

Ответ 2

Если ptr указывает на байт A или D, зависит от конечности машины. ptr указывает на этот байт целого числа, расположенного на самом нижнем адресе (остальные байты будут в ptr+1,...).

На машине большого конца самый старший байт целого числа (который 0x00) будет сохранен на этом младшем адресе, поэтому функция вернет нуль.

На litte-endian машине обратное, наименьший значащий байт целого числа (0x01) будет сохранен с наименьшим адресом, поэтому функция вернет его в этом случае.

Ответ 3

Это использует тип punning для доступа к целому числу в виде массива символов. Если машина является большой энтикой, это будет главный байт и будет иметь значение 0, но если машина немного ориентирована, это будет младший байт, который будет иметь значение один. (Вместо того, чтобы обращаться к i как к единому целому числу, к одной и той же памяти обращается массив из четырех символов).

Ответ 4

Является ли *((char*)&i) байтом A или байтом D, попадает в сердце утверждения. В маленькой системной системе целое число 0x41424344 будет выложено в память как: 0x44 43 42 41 (младший старший байт, в ASCII, это "DCBA" ). В большой системной системе он будет выложен как: 0x41 42 43 44. Указатель этого целого будет содержать адрес первого байта. Учитывая указатель как целочисленный указатель, и вы получите целое число. Рассмотрим указатель как указатель char, и вы получите первый байт, так как размер char.

Ответ 5

Конечно,

Давайте посмотрим

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

Если машина маленькая, то данные будут в * ptr будут 0000 0001.

Если машина Big Endian, тогда данные будут инвертированы, то есть я буду

i = 0000 0000 0000 0001 0000 0000 0000 0000 

Итак, * ptr будет содержать 0x0

Наконец, return * ptr эквивалентен

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

else //big endian

Ответ 6

Предположим, что int - 4 байта (в C это может и не быть). Это предположение просто для упрощения примера...

Вы можете посмотреть каждый из этих 4 байтов отдельно.

char является байтом, поэтому он смотрит на первый байт 4-байтового буфера.

Если первый байт не равен 0, то это говорит вам, если младший бит содержится в первом байте.

Я случайно выбрал число 42, чтобы избежать путаницы какого-либо специального значения в значении 1.

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

Структура:

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

Если firstByteOf4Is42 верно, у вас есть мало-endian. Если lastByteOf4Is42 истинно, тогда у вас есть большой-endian.