Доступ к отдельным битам переменных - PullRequest
0 голосов
/ 07 мая 2019

В моем приложении у меня есть 2 переменные (shift_counter и shift_counter_copy).Что мне нужно сделать, это взять младший байт Shift_counter и манипулировать битами.Сначала я копирую значение в shift_counter в переменную shift_counter_copy.Затем я опрашиваю отдельные биты в младшем байте shift_counter и основываясь на наборе результатов или очищаю определенные биты в младшем байте переменной shift_counter_copy.Я написал следующий код:

`void reverse_byte ()
{
    uint8_t n ;
    For (n=0; n<7; n++)
    {
        If (shift_counter(n) == 1 )
        {
            shift_counter_copy(7-n) = 1;
        }
        else
        {
            shift_counter_copy(7-n) = 0;
        }
    }
    shift_counter &= 0xFF00 ;
    shift_counter | shift_counter_copy ;
};

, но тогда я не был уверен, что компилятор примет показанный метод для адресации отдельных битов.Я думал, что "struct" может сработать, к чему я написал;

stuct shift_counter
(
    shift_counter_0 [1];
    shift_counter_1 [1];
    shift_counter_2 [1];
    shift_counter_3 [1];
    shift_counter_4 [1];
    shift_counter_5 [1];
    shift_counter_6 [1];
    shift_counter_7 [1];
    shift_counter_8 [1];
    shift_counter_9 [1];
    shift_counter_10 [1];
    shift_counter_11 [1];
    shift_counter_12 [1];
    shift_counter_13 [1];
    shift_counter_14 [1];
    shift_counter_15 [1];
);

Но, подумав об этом, я не думаю, что она будет работать с моим циклом "for", так как компилятор будет искать весьНазвание каждого бита.Есть ли в C методы, которые позволили бы получить доступ к каждому биту переменной, чтобы человек мог выполнить цикл FOR, как указано выше?Или пользователь застрял бы, используя маски, чтобы получить значение каждого бита?Или можно создать определение, например:

define shift_counter (1) = shift_counter_1;

и повторить это для остальных битов в "struct".

Любая и вся помощь приветствуется.

1 Ответ

1 голос
/ 07 мая 2019

В директивах препроцессора можно ставить конкатенацию, используя ##

#define shift_counter(n) shift_counter_ ## n

, поэтому shift_counter(1) будет заменено на shift_counter_1 перед компиляцией.Но он работает ТОЛЬКО с исходным кодом во время компиляции.Т.е. shift_counter(7-n) будет заменено на shift_counter_7-n, вы не сможете использовать его во время выполнения.

Но я не могу понять, зачем вам нужен такой сложный подход для работы с битами?Просто используйте эти шаблоны (предположим, у вас есть целочисленная переменная a):

a |= (1 << n); // set n'th bit
a &= ~(1 << n); // clear n'th bit
a ^= (1 << n); // invert n'th bit
if ((a & (1 << n)) != 0) ... // check if n'th bit is set

Например:

uint16_t shift_counter_copy = 0;
for (int i = 0 ; i < 8; i++) {
  if ((shift_counter & (1 << i)) != 0) {  // if i'th bit in shift_counter is set
    shift_counter_copy |= (1 << (7 - i)) // set (7-i)'th bit in shift_counter_copy
  } else {
    shift_counter_copy &= ~(1 << (7 - i)) // else clear (actually not needed, since shift_counter_copy initialized to zero)
  }
}
...