如何在 c 中创建位图数据?

how can I create a bitmaped data in c?

我正在尝试在 中创建位图数据,这是我使用的代码,但我无法找出正确的逻辑。这是我的代码

bool a=1;
bool b=0;
bool c=1;
bool d=0;

uint8_t output = a|b|c|d;

printf("outupt = %X", output);

我希望输出为“1010”,相当于十六进制“0x0A”。我该怎么做??

按位或运算符s每个位置的位。 a|b|c|d 的结果将是 1 因为你在 最小 重要位置按位 ing 0 和 1 .

您可以像这样将位移动 (<<) 到正确的位置:

uint8_t output = a << 3 | b << 2 | c << 1 | d;

这将导致

    00001000 (a << 3)
    00000000 (b << 2)
    00000010 (c << 1)
  | 00000000 (d; d << 0)
    --------
    00001010 (output)

严格来说,计算发生在 ints 并且中间结果有更多的前导零,但在这种情况下我们不需要关心。

如果您对 setting/clearing/accessing 非常简单的特定位感兴趣,您可以考虑 std::bitset:

bitset<8> s;   // bit set of 8 bits

s[3]=a;        // access individual bits, as if it was an array
s[2]=b;
s[1]=c; 
s[0]=d;        // the first bit is the least significant bit

cout << s <<endl;       // streams the bitset as a string of '0' and '1' 
cout << "0x"<< hex << s.to_ulong()<<endl;    // convert the bitset to unsigned long
cout << s[3] <<endl;     // access a specific bit
cout << "Number of bits set: " << s.count()<<endl; 

Online demo

优点是代码更易于阅读和维护,尤其是在修改位图数据时。因为使用 <<| 运算符组合的二进制算术来设置特定位,如 所解释的那样是一个可行的解决方案。但是,通过结合使用 <<~(创建位掩码)与 & 来清除现有位图中的特定位有点棘手。

另一个优点是您可以轻松管理数百位的大型位集,比最大的 built-in 类型 unsigned long long 大得多(尽管这样做无法轻松转换为unsigned long 或 unsigned long long:你必须通过字符串)。

仅C

我会使用位域。我知道它们不可移植,但对于特定的嵌入式硬件(尤其是 uC),它的定义很明确。

#include <string.h>
#include <stdio.h>
#include <stdbool.h>


typedef union 
{
    struct 
    {
        bool a:1;
        bool b:1;
        bool c:1;
        bool d:1;
        bool e:1;
        bool f:1;
    };
    unsigned char byte;
}mydata;


int main(void)
{
    mydata d;

    d.a=1;
    d.b=0;
    d.c=1;
    d.d=0;

printf("outupt = %hhX", d.byte);
}