Макрос Test_bit в C / C ++ - PullRequest
       4

Макрос Test_bit в C / C ++

0 голосов
/ 07 мая 2018

Я пытаюсь прочитать ввод устройства linux через ioctl (), и я видел на многих примерах кода с макросом «test_bit», но единственный код, который я нашел об этом, это: #define test_bit(bit, array) (array[bit / 8] & (1 << (bit % 8))), и это не так Работа. Я пришел к выводу, что, возможно, есть что-то, что нужно включить в мой класс, чтобы иметь этот макрос. Кто-нибудь может мне помочь с этим, я несколько дней застрял с этой проблемой? Спасибо

Редактировать: Вот код, который я использую:

void test(){
uint8_t key_b[KEY_MAX/8 + 1];
/* the events (up to 64 at once) */
const char *keyboard = "/dev/input/keyboard0";
int keybrdToCapture;
int yalv;
keybrdToCapture = open(keyboard, O_RDONLY);

memset(key_b, 0, sizeof(key_b));
ioctl(keybrdToCapture, EVIOCGKEY(sizeof(key_b)), key_b);

for (yalv = 0; yalv < KEY_MAX; yalv++) {

    if (test_bit(yalv, key_b)) {
        switch ( yalv)
            {
            case 0x1c :
                dial->setMessage("Enter");
                dial->show();
                break;
            case 0x66 :
                dial->setMessage("Home");
                dial->show();
                break;
            case 0x3b :
                dial->setMessage("F1");
                dial->show();
                break;
            case 0x3c :
                dial->setMessage("F2");
                dial->show();
                break;
            default:
                dial->setMessage("Unknow for now");
                dial->show();
            }
    }
}

}

1 Ответ

0 голосов
/ 07 мая 2018

Это небольшой пример, показывающий, как можно использовать test_bit. (Я переименовал его в TEST_BIT и объясню ниже, почему.):

#include <iomanip>
#include <iostream>

#define TEST_BIT(bit, array) (array[bit / 8] & (1 << (bit % 8)))

int main()
{
  unsigned char data[] = {
    (unsigned char)0xde,
    (unsigned char)0xad,
    (unsigned char)0xbe,
    (unsigned char)0xef
  };
  enum { nData = sizeof data / sizeof *data };
  enum { nDataBits = 8 * nData };
  for (unsigned i = 0; i < nDataBits; ++i) {
    std::cout << "Bit " << std::setw(2) << i << ": "
      << (TEST_BIT(i, data) ? 1 : 0) << '\n';
  }
  return 0;
}

Выход:

Bit  0: 0
Bit  1: 1
Bit  2: 1
Bit  3: 1
Bit  4: 1
Bit  5: 0
Bit  6: 1
Bit  7: 1
Bit  8: 1
Bit  9: 0
Bit 10: 1
Bit 11: 1
Bit 12: 0
Bit 13: 1
Bit 14: 0
Bit 15: 1
Bit 16: 0
Bit 17: 1
Bit 18: 1
Bit 19: 1
Bit 20: 1
Bit 21: 1
Bit 22: 0
Bit 23: 1
Bit 24: 1
Bit 25: 1
Bit 26: 1
Bit 27: 1
Bit 28: 0
Bit 29: 1
Bit 30: 1
Bit 31: 1

Демонстрация жизни на колиру

Обратите внимание:

  1. Функциональные макросы - плохой выбор в C ++. Гораздо лучше встроенные функции, потому что макросы не являются типобезопасными, а функции. В этом случае подходящей альтернативой может быть, например ::

    inline bool test_bit(unsigned bit, unsigned char *array)
    {
      return array[bit / 8] & (1 << (bit % 8)) != 0;
    }
  2. Макросы должны именоваться только заглавными буквами. Макросы обрабатываются до начала фактической компиляции C ++. Следовательно, они полностью находятся за пределами определенного пространства имен. Это может иметь неожиданные последствия. Следовательно, прописные имена делают их немного эксклюзивными. (Или лучше использовать inline-функции, когда это возможно.)

  3. Макрос выделяет бит из байтового массива. Таким образом, изолированное значение может быть 1, 2, 4, 8, 16, 32, 64, 128 в зависимости от того, какой бит проверен (результат 1 << (bit % 8)), если соотв. бит установлен. Это не проблема, если нужно значение истинности, так как все! = 0 считается истинным. Если подразумевается 0 или 1, то результат test_bit() или TEST_BIT() следует дополнительно сравнить с 0.

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