2012-06-16 3 views
0

Я прочитал этот код в библиотеке, которая используется для отображения растрового изображения (.bmp) на ЖК-дисплее.
Мне очень трудно понять , что происходит по следующим строкам, и как это действительно так.Поймите следующую строку

Возможно, кто-то может объяснить это мне.

uint16_t s, w, h; 
uint8_t* buffer; // does get malloc'd 

s = *((uint16_t*)&buffer[0]); 
w = *((uint16_t*)&buffer[18]); 
h = *((uint16_t*)&buffer[22]); 

Я предполагаю, что это не так уж трудно для реального C программист, но я все еще учусь, так что я просто спросить :)
Насколько я понимаю, он прилипает как-то вместе две uint8_t переменные a uint16_t.

Заранее за вашу помощь здесь!

ответ

2

В коде, который вы указали, считывается buffer (который представляет собой массив байтов), а значения извлекаются в s, w и h.

(uint16_t*)&buffer[n] синтаксиса означает, что вы извлечение адреса п го байта buffer, и приведения его в uint16_t*. Кастинг подсказывает компилятору посмотреть на этот адрес, как если бы точки на uint16_t, , т. Е., пара uint8_t.
Дополнительный * в коде разведения указателя, i.e. извлекает значение с этого адреса. Поскольку адрес теперь указывает на uint16_t, извлекается значение uint16_t.

В результате:

  1. s получает значение первого uint16_t, т.е. байт 0 и 1.
  2. w получает значение десятого uint16_t, т.е. байта 18 и 19 .
  3. h получает значение twelveth uint16_t, т.е. байт 22 и 23.
+0

поэтому, если буфер [0] = 4; и буфер [1] = 2; s будет в этом случае 516? –

+1

Это зависит от того, какой байт рассматривается как MSB. Если 0-й байт является MSB, то ваш номер равен 0x0402 = 1026. Если 1-й байт является MSB, то он равен 0x0204 = 516. –

+1

516 или 1026, в зависимости от сущности процессора ... –

1
uint8_t* buffer; // pointer to 8 bit or simply one byte 

Buffer указывает на адрес памяти байт -> | byte0 | Байт 1 | byte2 | ....

(uint16_t*)&buffer[0] // &buffer[0] is actually the same as buffer 

(uint16_t*)&buffer[0] равна (uint16_t*)buffer; это указывает на 16 бит или полуслова

(uint16_t*)buffer указывает на память: | byte0byte1 = halfword0 | byte2byte3 = halfword1 | ....

w = *((uint16_t*)&buffer[18]); 

принимает адрес памяти в байт 18 в буфере, а затем переинтерпретировать этот адрес адрес полуслова, затем получает половину слова по этому адресу; это просто ш = byte18 и byte19 наклеить вместе, образуя полуслово

h = *((uint16_t*)&buffer[22]); 

ч = byte22 и байты 23 приклеиваются вместе

UPD Более подробное объяснение:

h = *((uint16_t*)&buffer[22]) =>

1) buffer[22] === 22nd uint8_t (a.k.a.байт) буфера; назовем его byte22

2) &buffer[22] === & byte === адрес byte22 в памяти; он имеет тип uint8_t *, как и буфер; letcall it byte22_address;

3) (uint16_t*)&buffer[22] = (uint16_t *) byte22_address; отправляет адрес байта в адрес (два байта, склеенных вместе, адрес полуслова с тем же адресом, назовем его полусловом11_адрес;

4) h = *((uint16_t*)&buffer[22]) === * halfword11_address; * оператор принимает значение по адресу, то есть 11-й полуслова или байты 22 и 23, склеенные вместе;

1

Код:

  • занимает два байта в положениях 0 и 1 в буфере, вставляет их вместе в беззнаковое 16-битное значение, и сохраняет результат в s;
  • он делает то же самое с байтами 18/19, сохраняя результат в w;
  • ditto для байтов 22/23 и h.

Стоит отметить, что код использует родную endianness целевой платформы, чтобы решить, какой из двух байт представляет верхние 8 бит результата, и который представляет нижние 8 бит.

Смежные вопросы