C中的按位逻辑

Leo*_*eon 2 c binary bit operator-keyword

我对按位操作有一定的了解,但这个功能只是我的头脑.

void binary_print(unsigned int value) {
  unsigned int mask = 0xff000000;   // Start with a mask for the highest byte.
  unsigned int shift = 256*256*256; // Start with a shift for the highest byte.
  unsigned int byte, byte_iterator, bit_iterator;

  for (byte_iterator=0; byte_iterator < 4; byte_iterator++) {
    byte = (value & mask) / shift; // Isolate each byte.
    printf(" ");

    for (bit_iterator=0; bit_iterator < 8; bit_iterator++) {
      // Print the byte's bits.
      if (byte & 0x80) // If the highest bit in the byte isn't 0,
        printf("1");   // print a 1.
      else
        printf("0");   // Otherwise, print a 0.

      byte *= 2;       // Move all the bits to the left by 1.
    }
    mask /= 256;       // Move the bits in mask right by 8.
    shift /= 256;      // Move the bits in shift right by 8.
  }
}
Run Code Online (Sandbox Code Playgroud)

此函数接收函数的位标志,open()并在display_flags函数的帮助下生成以下输出,该函数添加了适当的标签:

O_RDONLY : 0 : 00000000 00000000 00000000 00000000
O_WRONLY : 1 : 00000000 00000000 00000000 00000001
O_RDWR : 2 : 00000000 00000000 00000000 00000010
O_APPEND : 1024 : 00000000 00000000 00000100 00000000
O_TRUNC : 512 : 00000000 00000000 00000010 00000000
O_CREAT : 64 : 00000000 00000000 00000000 01000000
O_WRONLY|O_APPEND|O_CREAT : 1089 : 00000000 00000000 00000100 01000001 
Run Code Online (Sandbox Code Playgroud)

我理解输出没有问题,但我不明白实际过程:

  1. 如何byte = (value & mask) / shift隔离个别位?
  2. 为什么if(byte & 0x80)意思是"如果字节中的最高位不是0?"
  3. 如何做这些线路:byte *= 2;,mask /= 256;shift /= 256;移动位,这是为什么操作显著?

Phi*_*ler 10

1.如何byte = (value & mask) / shift隔离单个位?

mask是一个位模式,总是有8个连续的位设置为1,其余的位设置为0(它开始于0xff000000,然后0x00ff0000,依此类推.所以,当你取位和maskvalue,所有位value将被设置为0,除了那些对应于指定的字节mask.那些保留它们的值.

shift被设置为相应的值,通过除法,shift正好在掩蔽中存活的那些位将最终位于最右边的位中(参见问题3的答案如何工作).

因此假设value0xDEADBEEF,mask具有其初始值0xff000000,并shift具有其初始值256*256*256.然后value & mask0xDE000000,最后的结果是0x000000DE.

在二进制中,例子是

value       = 11011110101011011011111011101111
mask        = 11111111000000000000000000000000
byte & mask = 11011110000000000000000000000000
result      = 00000000000000000000000001101111
Run Code Online (Sandbox Code Playgroud)

2.为什么if(byte & 0x80)意思是"如果字节中的最高位不是0?"

这里代码作者认为byte是一个8位变量.虽然它在技术上更大,但这里从不使用更高的位.因此,当作者提到"最高位"时,请考虑右边的第8位(如果byte实际上只有一个字节的大小,则会出现最高位).

现在请注意,它0x8010000000二进制的.所以当你拿走时,除了"最高"(右边第8个)之外byte & 0x80,所有位byte都将被设置为0.因此byte & 0x80,如果最高位byte为零,并且大于零,则为零,如果"最高"位byte为1.

3.如何做这些线路:byte *= 2;,mask /= 256;shift /= 256;移动位,这是为什么操作显著?

乘以2相当于向左移位1.用例如值9,它是1001二进制的.乘以2得到18,它是10010二进制的.

类似于除以2,这是向右移位1.除以256相当于8除以2,因此除以256相当于右移8位.这里使用这些操作例如将值mask从,更改0xff0000000x00ff0000,0x0000ff00最后更改为0x000000ff.

完整功能的描述

有了这些知识,我们就可以看到完整功能的作用.在外部循环中,它循环遍历4个字节value,从最左边的一个字节开始,到最右边的一个字节结束.它通过屏蔽当前字节并将其存储在其中来实现byte.

然后内部循环遍历存储的8位byte.它始终从右侧看第8位并相应地打印1或0.然后它将位移到左边,这样在第二次迭代中,右边第7位的位现在是右边的第8位,将被打印,然后是下一位等,直到所有8位打印在右边 - - 左撇子.

编写此函数的另一种方法是

for (int i = 31; i >= 0; i--) {
  if (value & (1 << i))
    printf("1");
  else
    printf("0");

  if (i % 8 == 0)
    printf(" ");
}
Run Code Online (Sandbox Code Playgroud)

这将简单地value以从左到右的顺序遍历所有位.表达式value (1 << i)选择所需的位value,从右边的第32个开始(当i为31时),从右边的第1个开始(当i为0时).