Может кто-нибудь объяснить эту функцию C? - PullRequest
0 голосов
/ 17 апреля 2009

У меня есть некоторые проблемы с этим синтаксисом. Может ли кто-нибудь объяснить мне, что делает эта функция C?

unsigned long protodec_henten(int from, int size, unsigned char *frame)
{
   int i = 0;
   unsigned long tmp = 0;

   for (i = 0; i < size; i++)
     tmp |= (frame[from + i]) << (size - 1 - i);

   return tmp;
}

Спасибо!

Ответы [ 7 ]

15 голосов
/ 17 апреля 2009

Полагаю, вы ссылаетесь на следующую строку как строку с запутанным синтаксисом.

tmp |= (frame[from + i]) << (size - 1 - i);

Давайте разберемся с этим

  • frame [from + i]: «from» представляет начальный индекс в массиве, а i - просто текущее смещение. Так что это эффективно итерирует массив, начиная с индекса "from"
  • size - 1 - i: Это вычисляет количество битов для сдвига и делает это на основе текущего индекса. Это число будет начинаться с размера -1 и будет уменьшаться по мере прохождения цикла
  • (frame [from + i] << (size - 1 - i): это сдвигает значение на from + i на указанное количество бит </li>
  • tpm | = ...: Делает побитовое выражение Или для байтов, которые все еще доступны после смещения итерированного значения.
7 голосов
/ 17 апреля 2009

Другие уже описали каждую строку, поэтому я просто добавлю, что функция делает . Вы можете представить байты в frame между позициями (from) и (from+size) в «стеке» с другой позицией. Первый байт будет размещен слева.

bits from:      tmp: |    +  +     |(LSB-side of tmp)
frame[from]:           ---+----
frame[from+1]:          -----+--
frame[from+2]:           -+------
...

Теперь бит tmp установлен, если какой-либо из байтов "ниже" имеет бит, установленный в соответствующей позиции.

2 голосов
/ 17 апреля 2009

выглядит как упаковщик битов. Если, как предположил Эрик, все символы в frame равны нулю или единице, то это займет size символов и упакует их значения в tmp. Например, если frame (со смещением start) содержит значения 00 01 00 00 01 01 01 00, то protodec_henten(0,8,frame) вернет (без начальных нулей) 0x4E (или 01001110 в двоичном виде). Есть лучшие способы сделать это, так что это может быть что-то еще, но трудно сказать, что.

0 голосов
/ 17 апреля 2009

Этот общий код просто копирует диапазон данных в переменную tmp. На самом деле, это просто трудная попытка памяти.

Почему бы просто не сделать: memcpy (& tmp, frame + from, size)

0 голосов
/ 17 апреля 2009

Из-за побитового ИЛИ эта функция имеет смысл, только если все значения в frame равны 0 или 1.

В этом случае он поместит size последовательных значений (т.е. битов) frame, начиная с индекса from, в один unsigned long. Последний бит (с индексом from+size-1) будет вставлен как младший бит.

0 голосов
/ 17 апреля 2009

Полагаю, вы не понимаете tmp |=, потому что это, вероятно, единственная часть кода, которую сложно понять. Если вы попытаетесь найти операторы C, вы найдете список здесь , теперь |= означает «Побит или», вы можете узнать больше о них здесь .

Итак, что на самом деле делает этот код, так это то, что он требует некоторого ввода, вы указываете функции, где начинать чтение в «буфере» / «фрейме», и вы делаете побитовое или на столько позиций, сколько указано в параметре «размера».

0 голосов
/ 17 апреля 2009

Похоже на хеш-функцию. Если подумать, это может сделать довольно плохую хеш-функцию.

Они сдвигают каждый кадр на оставшуюся часть размера, а затем ИЛИ со статическим значением. Это значение затем возвращается.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...