迭代 C 中的位

问题描述 投票:0回答:6

我有一个很大的 char *str ,其中前 8 个字符(如果我没记错的话等于 64 位)代表一个位图。有什么方法可以迭代这 8 个字符并查看哪些位为 0?我在理解位的概念时遇到了很多困难,因为你无法在代码中“看到”它们,所以我想不出任何方法来做到这一点。

c bit bitarray
6个回答
16
投票

想象你只有一个字节,一个字符

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 位来说,这并不是一个非常技术性的描述。


6
投票

这是一种迭代无符号整数的每个设置位的方法(使用无符号而不是有符号整数来实现明确定义的行为;任何宽度的无符号都应该没问题),一次一位。

定义以下宏:

#define LSBIT(X)                    ((X) & (-(X)))
#define CLEARLSBIT(X)               ((X) & ((X) - 1))

然后您可以使用以下习惯用法来迭代设置的位,首先是 LSbit:

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
循环中以一次处理一个字节/字。


3
投票

在C语言中,字符是8位宽的字节,通常在计算机科学中,数据是围绕字节作为基本单位来组织的。

在某些情况下,例如您的问题,数据作为布尔值存储在各个位中,因此我们需要一种方法来确定特定字节中的特定位是打开还是关闭。已经有一个 SO 解决方案来解释如何在 C 中进行位操作

要检查某个位,通常的方法是将其与要检查的位进行与:

int isBitSet = bitmap & (1 << bit_position);

如果此操作后变量 isBitSet 为 0,则该位未被设置。任何其他值都表示该位已打开。


3
投票

对于小端存储架构来说是这样的:

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...
  }
}

3
投票

对于一个字符

b
,你可以简单地像这样迭代:

for (int i=0; i<8; i++) {
  printf("This is the %d-th bit : %d\n",i,(b>>i)&1);
}

然后您可以根据需要迭代这些字符。

你应该明白的是,你不能直接操作这些位,你只能使用以 2 为基数的数字的一些算术属性来计算以某种方式代表你想知道的一些位的数字。

例如,它是如何工作的?一个字符有 8 位。一个 char 可以看作是一个以 2 为基数的 8 位数字。如果 b 中的数字是 b7b6b5b4b3b2b1b0 (每个数字都是一个数字),那么 b>>i 就是 b 向右移动 i 个位置(左边的 0 被压入) )。因此,10110111 >> 2 是 00101101,然后运算 &1 隔离最后一位(按位与运算符)。


0
投票

如果你想迭代所有字符。

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
...
© www.soinside.com 2019 - 2024. All rights reserved.