我有一个大的char *str,其中前8个字符(如果我没记错的话等于64位)表示位图。有没有办法遍历这8个字符并查看哪些位是0?我很难理解比特概念,因为你无法在代码中“看到”它们,所以我无法想出任何方法来执行此操作。
我有一个大的char *str,其中前8个字符(如果我没记错的话等于64位)表示位图。有没有办法遍历这8个字符并查看哪些位是0?我很难理解比特概念,因为你无法在代码中“看到”它们,所以我无法想出任何方法来执行此操作。
想象一下你只有一个字节,一个单独的字符my_char
。你可以使用位运算符和位移来测试各个位。
unsigned char my_char = 0xAA;
int what_bit_i_am_testing = 0;
while (what_bit_i_am_testing < 8) {
if (my_char & 0x01) {
printf("bit %d is 1\n", what_bit_i_am_testing);
}
else {
printf("bit %d is 0\n", what_bit_i_am_testing);
}
what_bit_i_am_testing++;
my_char = my_char >> 1;
}
对你来说可能比较新的部分是 >>
运算符,该运算符将“在左侧插入零并将每个位向右移动,最右侧的位将被丢弃”。
这并不是一个非常技术性的描述,它表示将数字向右移动1位。
my_char
声明为unsigned
。 - barak manosmy_char = my_bitmap[1234];
- Vinicius Kamakura#define LSBIT(X) ((X) & (-(X)))
#define CLEARLSBIT(X) ((X) & ((X) - 1))
接下来您可以使用以下成语来迭代集合位,从最低位开始:
unsigned temp_bits;
unsigned one_bit;
temp_bits = some_value;
for ( ; temp_bits; temp_bits = CLEARLSBIT(temp_bits) ) {
one_bit = LSBIT(temp_bits);
/* Do something with one_bit */
}
我不确定这是否符合您的需求。您说您想检查0
位,而不是1
位——也许您可以对初始值进行按位取反操作。另外,对于多字节值,您可以将其放入另一个for
循环中,以逐个处理一个字节/字。
int isBitSet = bitmap & (1 << bit_position);
s/8-bit wide/at least 8-bit wide
- The Paramagnetic CroissantCHAR_BIT
宽的字节。 CHAR_BIT
至少为8。 - chux - Reinstate MonicaCHAR_BIT != 8
的现状。2)由于C语言不要求新系统使用CHAR_BIT == 8
,未来的系统可能会使用超级八位组char
。 - chux - Reinstate Monicaint
,因此int
溢出应该是明确定义的。由于C规范将int
溢出定义为未定义以适应那些老旧的、令人讨厌的符号-幅度、1的补码、填充整数,更聪明的编译器利用了这一点,并创建了破坏先前依赖于明确定义的2的补码溢出的代码。为什么程序员们会依赖于明确定义的2的补码溢出——因为“所有”现代系统都使用2的补码。 - chux - Reinstate MonicaCHAR_BIT
可能大于8的优势进行一些未来的优化。如果代码需要一个8位整数,请建议使用 (u)int8_t
。 - chux - Reinstate Monica这在小端内存架构中是正确的:
const int cBitmapSize = 8;
const int cBitsCount = cBitmapSize * 8;
const unsigned char cBitmap[cBitmapSize] = /* some data */;
for(int n = 0; n < cBitsCount; n++)
{
unsigned char Mask = 1 << (n % 8);
if(cBitmap[n / 8] & Mask)
{
// if n'th bit is 1...
}
}
对于一个字符b
,您可以这样简单地迭代:
for (int i=0; i<8; i++) {
printf("This is the %d-th bit : %d\n",i,(b>>i)&1);
}
<limits.h>
并将8
更改为CHAR_BIT
。 - barak manoschar b
等于二进制值10110111
,并且你执行b >> 2
,你得到的是11101101
,而不是00101101
。这是因为默认情况下char
是signed char
,当对signed
变量进行右移操作时,符号位会跟随向右移动。要使b >> 2
产生00101101
,你必须声明unsigned char b
。 - barak manos如果你想遍历所有字符。
char *str = "MNO"; // M=01001101, N=01001110, O=01001111
int bit = 0;
for (int x = strlen(str)-1; x > -1; x--){ // Start from O, N, M
printf("Char %c \n", str[x]);
for(int y=0; y<8; y++){ // Iterate though every bit
// Shift bit the the right with y step and mask last position
if( str[x]>>y & 0b00000001 ){
printf("bit %d = 1\n", bit);
}else{
printf("bit %d = 0\n", bit);
}
bit++;
}
}
输出
Char O
bit 0 = 1
bit 1 = 1
bit 2 = 1
bit 3 = 1
bit 4 = 0
bit 5 = 0
bit 6 = 1
bit 7 = 0
Char N
bit 8 = 0
bit 9 = 1
bit 10 = 1
...