Что означает этот синтаксис pData [1 + 2 * i] << 8 | pData [2 + 2 * i] C ++? - PullRequest
2 голосов
/ 11 января 2011

что такое значение pData[1+2*i]<<8|pData[2+2*i], где pData[ ] - массив, содержащий данные BYTE?У меня есть следующая функция в основной функции

{
..........
....
BYTE Receivebuff[2048];
..
ReceiveWavePacket(&Receivebuff[i], nNextStep);
....
...
..
}

Где Receivebuff - это массив типа BYTE.

ReceiveWavePacket(BYTE * pData, UINT nSize)
{
 CString strTest;
 for(int i = 0 ; i < 60 ; i++)
 {
  strTest.Format("%d\n",(USHORT)(pData[1+2*i]<<8|pData[2+2*i]));
  m_edStatData.SetWindowTextA(strTest);
          }
}

Я хочу знать значение ",(USHORT)(pData[1+2*i]<<8|pData[2+2*i]).

Может ли какое-нибудь тело помочь мне?

Ответы [ 3 ]

12 голосов
/ 11 января 2011

Кажется, это код для синтеза 16-битного значения из двух восьмибитных значений.Если вы заметите, математика имеет форму

(a << 8) | b

Для подходящих а и б.Эта первая часть, (a << 8), берет восемь битов в a и сдвигает их на восемь позиций, давая 16-битное значение, первые восемь битов которого являются битами от a, а вторые восемь битов равны нулю.Применение побитового оператора ИЛИ между этим новым значением и значением b создает новое шестнадцатиразрядное значение, первые восемь битов которого являются битами a (поскольку расширение нуля b для шага ИЛИ оставляет эти биты нетронутыми) и чьи младшие восемь битовбиты b, так как ORing нулевых битов с битами b приводит к b. </p>

0 голосов
/ 11 января 2011

@ templatetypedef является правильным, но здесь происходит еще одна интересная вещь:

(pData[1+2*i]<<8|pData[2+2*i])

i идет от 0 до 59, поэтому будет обработано 60 слов, начиная с pData[1] (1 + 2 * 0 == 1).
Это означает, что первый байт в массиве никогда не обрабатывается, что выглядит странно.Почему это не более естественно pData[2*i]<<8|pData[2*i+1]?

Одна возможность: данные Word могут быть сохранены в потоке байтов двумя способами: слово 0xAA11 может быть сохранено как 0xAA 0x11 или 0x11 0xAA.Представь, что это последнее.

Для слов: 0xAA11 0xBB22 0xCC33 ...
Поток байтов будет 11 AA 22 BB 33 CC ...

При синтаксическом анализе «естественного» метода получится 0x11AA 0x22BB..., что, очевидно, неверно.

Этот код напечатает 0xAA22 0xBB33, 0xCC44 ...., который, вероятно, пройдет проверку на разумность, но на самом деле совершенно неверен.

Я надеюсь, что дополнительные +1 не были добавлены, чтобы "исправить"проблема порядка байтов.

0 голосов
/ 11 января 2011

Я думаю, что @templatetypedef правильный, он выглядит как код, который создает 16-битное значение путем логического ИЛИ с двумя 8-битными значениями. (так как он или два элемента из вашего массива байтов).

Логическое ИЛИ из двух битов в основном означает, что если один из битов равен 1, то результат равен 1 («этот бит ИЛИ этот бит»).

В качестве дополнительного примера рассмотрим эту функцию, которая берет указатель на символ (размером 8 бит) и возвращает целое число (в этой реализации это означает 32 бита).

int Read32(const char *pcData)
{
    return ( (pcData[3]<<24) & 0xff | pcData[2]<<16 | pcData[1]<<8 | pcData[0]);
}

Если pcData - указатель на массив char - тогда он берет третий найденный символ и сдвигает его на 24 бита:

, например

если pcData[3] было 10110001, то теперь

10110001000000000000000000000000

Он принимает это 32-битное значение, а затем ИЛИ с помощью pcData [2], смещенного на 16 битов, что означает, что если pcData[2] равно 11111111, то 32-битное значение теперь равно:

10110001111111110000000000000000

и т. Д. С pcData[1] и pcData[0].

...