如何在 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)
严格来说,计算发生在 int
s 并且中间结果有更多的前导零,但在这种情况下我们不需要关心。
如果您对 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;
优点是代码更易于阅读和维护,尤其是在修改位图数据时。因为使用 <<
和 |
运算符组合的二进制算术来设置特定位,如 所解释的那样是一个可行的解决方案。但是,通过结合使用 <<
和 ~
(创建位掩码)与 &
来清除现有位图中的特定位有点棘手。
另一个优点是您可以轻松管理数百位的大型位集,比最大的 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);
}
我正在尝试在 中创建位图数据,这是我使用的代码,但我无法找出正确的逻辑。这是我的代码
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)
严格来说,计算发生在 int
s 并且中间结果有更多的前导零,但在这种情况下我们不需要关心。
如果您对 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;
优点是代码更易于阅读和维护,尤其是在修改位图数据时。因为使用 <<
和 |
运算符组合的二进制算术来设置特定位,如 <<
和 ~
(创建位掩码)与 &
来清除现有位图中的特定位有点棘手。
另一个优点是您可以轻松管理数百位的大型位集,比最大的 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);
}