Существует множество способов записать этот вид алгоритма.Здесь я пойду с легким для понимания.Но сначала давайте изменим сигнатуру функции, чтобы использовать правильные типы:
#include <stdint.h>
uint8_t function(uint16_t p);
Мы преобразуем 16-разрядное целое число без знака в 8-разрядное, поэтому приведенная выше рекомендуемая подпись.Теперь об алгоритме.
Основная идея состоит в том, чтобы поместить бит, который мы хотим извлечь, в крайнее правое положение, чтобы мы могли получить его, используя & 1
, который обнулит все биты, кроме первогоодин.Это:
uint8_t right_most_bit = p & 1;
даст нам этот бит.Теперь мы хотим сохранить этот бит в правильном положении в q
.Для этого будет индекс i
.Итак:
q = q | (right_most_bit << i);
или просто:
q |= (right_most_bit << i);
Затем нам нужно поместить следующий после следующего бита p
в крайнее правое положение.Мы делаем это с помощью:
p = p >> 2;
или короче:
p >>= 2;
Таким образом, возникает проблема создания цикла, так что наш i
увеличивается на 1 на каждой итерации,Цикл должен закончиться, когда p
равен 0, с тех пор мы знаем, что больше не будет битов, которые можно извлечь.Преимущество заключается в том, что цикл будет выполняться только для минимально необходимого количества итераций.Итак,
for (unsigned i = 0; p != 0; i++)
Мы собрали все это вместе:
for (unsigned i = 0; p != 0; i++) {
uint8_t right_most_bit = p & 1;
q |= (right_most_bit << i);
p >>= 2;
}
Конечно, вы можете упростить это еще больше:
for (unsigned i = 0; p != 0; i++, p >>= 2) {
q |= ((p & 1) << i);
}
Собрав все это вместе:
uint8_t function(uint16_t p)
{
uint8_t q = 0;
for (unsigned i = 0; p != 0; i++, p >>= 2) {
q |= ((p & 1) << i);
}
return q;
}