Может ли кто-нибудь объяснить эту функцию "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.