C语言 遍历 C 中的位

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26411131/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 11:28:12  来源:igfitidea点击:

Iterate through bits in C

cbitbitarray

提问by user16655

I have a big char *str where the first 8 chars (which equals 64 bits if I'm not wrong), represents a bitmap. Is there any way to iterate through these 8 chars and see which bits are 0? I'm having alot of trouble understanding the concept of bits, as you can't "see" them in the code, so I can't think of any way to do this.

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

回答by Vinicius Kamakura

Imagine you have only one byte, a single char my_char. You can test for individual bits using bitwise operators and bit shifts.

想象一下,您只有一个字节,一个 char 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;
}

The part that must be new to you, is the >>operator. This operator will "insert a zero on the left and push every bit to the right, and the rightmost will be thrown away".

对您来说一定很陌生的部分是>>操作员。此运算符将“在左侧插入一个零并将每一位推到右侧,最右侧的将被丢弃”。

That was not a very technical description for a right bit shift of 1.

对于右移 1 来说,这不是一个非常技术性的描述。

回答by Craig McQueen

Here is a way to iterate over each of the set bits of an unsigned integer (use unsigned rather than signed integers for well-defined behaviour; unsigned of any width should be fine), one bit at a time.

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

Define the following macros:

定义以下宏:

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

Then you can use the following idiom to iterate over the set bits, LSbit first:

然后您可以使用以下习语来迭代设置位,首先是 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 */
}

I'm not sure whether this suits your needs. You said you want to check for 0bits, rather than 1bits — maybe you could bitwise-invert the initial value. Also for multi-byte values, you could put it in another forloop to process one byte at a time.

我不确定这是否适合您的需求。你说你想检查0位,而不是1位——也许你可以按位反转初始值。同样对于多字节值,您可以将其放入另一个for循环中以一次处理一个字节。

回答by Tyler Durden

In the C language, chars are 8-bit wide bytes, and in general in computer science, data is organized around bytes as the fundamental unit.

在 C 语言中,字符是 8 位宽的字节,一般在计算机科学中,数据是以字节为基本单位进行组织的。

In some cases, such as your problem, data is stored as boolean values in individual bits, so we need a way to determine whether a particular bit in a particular byte is on or off. There is already an SO solution for this explaining how to do bit manipulations in C.

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

To check a bit, the usual method is to AND it with the bit you want to check:

要检查一点,通常的方法是将它与要检查的位进行 AND 运算:

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

If the variable isBitSet is 0 after this operation, then the bit is not set. Any other value indicates that the bit is on.

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

回答by Jean-Baptiste Yunès

For one char byou can simply iterate like this :

对于一个字符,b您可以简单地像这样迭代:

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

You can then iterate through the chars as needed.

然后,您可以根据需要遍历字符。

What you should understand is that you cannot manipulate directly the bits, you can just use some arithmetic properties of number in base 2 to compute numbers that in some way represents some bits you want to know.

您应该理解的是,您不能直接操作这些位,您可以仅使用以 2 为底的数字的一些算术属性来计算以某种方式表示您想知道的某些位的数字。

How does it work for example ? In a char there is 8 bits. A char can be see as a number written with 8 bits in base 2. If the number in b is b7b6b5b4b3b2b1b0 (each being a digit) then b>>i is b shifted to the right by i positions (in the left 0's are pushed). So, 10110111 >> 2 is 00101101, then the operation &1 isolate the last bit (bitwise and operator).

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

回答by aralex

It's true for little-endian memory architecture:

小端内存架构也是如此:

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