Reading notes of C language programming (Chapter 12 - bit operation)

Posted by Jem on Wed, 23 Feb 2022 02:16:08 +0100

12.1 bitwise operators

C language provides six bitwise operators:

  • &: bitwise AND
  • |: bitwise OR
  • ^: bitwise XOR
  • ~: reverse
  • < <: move left
  • >>: shift right

12.1.1 bitwise sum operation

The bitwise and operator "&" is a binocular operator. Its function is the binary phase and phase corresponding to each of the two numbers involved in the operation. Only when the corresponding two binary bits are 1, the result bit is 1, otherwise it is 0. The number involved in the operation appears in the form of complement. For ex amp le 9&5:

 0000 1001 (9 (binary complement of)
&0000 0101 (5 (binary complement of)
=0000 0001 (1 (binary complement of)     

Bitwise and operations are usually used to clear 0 or reserve some bits.

#include <stdio.h>

int main() {
    int a = 9, b = 5, c;
    c = a & b;
    printf("%d&%d=%d", a, b, c);
}

12.1.2 bitwise OR operation

The bitwise OR operator "|" is a binocular operator. Its function is the binary phase or corresponding to each of the two numbers involved in the operation. As long as one of the corresponding two binary bits is 1, the result bit is 1. Both numbers involved in the operation appear as complements. For example, 9|5:

 0000 1001 (9 (binary complement of)
|0000 0101 (5 (binary complement of)
=0000 1101 (13 (binary complement of)  

Namely:

#include <stdio.h>

int main() {
    int a = 9, b = 5, c;
    c = a | b;
    printf("%d|%d=%d", a, b, c);// 9|5=13
}

12.1.3 bitwise XOR operation

The bitwise exclusive or operator '^' is a binocular operator. Its function is that the corresponding binaries of the two numbers involved in the operation are different or, when the two corresponding binaries are different (that is, when one of the two binary bits is 0 and the other is 1), the result is 1. The participating operands still appear as complements. Such as 9 ^ 5:

 0000 1001 (9 (binary complement of)
^0000 0101 (5 (binary complement of)
=0000 1100 (12 (binary complement of)  

Namely:

#include <stdio.h>

int main() {
    int a = 9, b = 5, c;
    c = a ^ b;
    printf("%d^%d=%d", a, b, c);// 9^5=12
}

12.1.4 inverse operation

The negation operator ~ is a monocular operator with right combination. Its function is to negate each binary bit of the number involved in the operation. For example ~9:

~0000 1001 (9 (binary complement of)
=1111 0110    

Namely:

#include <stdio.h>

int main() {
    int a = 9, b;
    b = ~a;
    printf("~%d=%d", a, b);// ~9=-10
}

12.1.5 shift left operation

The shift left operator "< <" is a binocular operator. Its function shifts all the binary bits of the operand on the left of "< <" to the left by several bits, and the number on the right of "<" specifies the number of bits to move. The high bits are discarded and the low bits are supplemented by 0. For example:

a=3;(3 The binary bit of is 0000 (0011)
a<<4=0011 0000

Namely:

#include <stdio.h>

int main() {
    int a = 3, b;
    b = a << 4;
    printf("%d<<4=%d", a, b);// 3<<4=48
}

12.1.6 shift right operator

The shift right operator "> >" is a binocular operator. Its function is to shift all binary bits of the operand on the left of "> >" to the right by several bits, and the number on the right of "> >" specifies the number of bits to be moved. It should be noted that for signed numbers, when moving to the right, the sign bit will move with it. When it is a positive number, the highest bit is supplemented by 0, while when it is a negative number, the symbol bit is 1. Whether the highest bit is supplemented by 0 or 1 depends on the provisions of the compiling system. For example:

a=15;(15 Binary of is 0000 (1111)
a>>2=0000 0011    

Namely:

#include <stdio.h>

int main() {
    unsigned int a = 15, b;
    b = a >> 2;
    printf("%d>>2=%d", a, b);// 15>>2=3
}

12.2 bit field (bit segment)

When some information is stored, it does not need to occupy a complete byte, but only several or one binary bit. For example, when storing a switching value, there are only two states: 0 and 1, and one binary can be used. In order to save storage space and make processing simple, C language provides a data structure called "bit field" or "bit segment".

The so-called "bit field" is to divide the binary bit in a byte into several different regions and explain the number of bits in each region. Each domain has a domain name, which allows you to operate by domain name in the program. In this way, several different objects can be represented by one byte binary field.

That is, different information can be stored in different bits of a byte to make full use of space.

12.2.1 definition of bit field and declaration of bit field variables

The definition syntax of bit field is as follows:

struct Bit field structure name {
  Type specifier bit domain name: Bit field length;
  ...
};

For example:

struct bs {
    int a:8;
    int b:2;
    int c:6;
};

Declaration of bit field variables: the same way as the description of structural variables. You can define first and then explain, define description at the same time or explain directly. For example:

// Description data is a bs variable, accounting for two bytes in total. Among them, bit field a occupies 8 places, bit field b occupies 2 places and bit field c occupies 6 places
struct bs {
    int a:8;
    int b:2;
    int c:6;
} data;

Notes on the definition of bit field:

  • A bit field must be stored in the same byte and cannot span two bytes. If there is not enough space left for one byte to store another bit field, the bit field shall be stored from the next unit. You can also intentionally start a bit field from the next cell.
// In this bit field definition, a occupies 4 bits of the first byte, the last 4 bits are filled with 0 to indicate not to use, b starts from the second byte, occupies 4 bits, and c occupies 4 bits
struct bs {
       unsigned a:4
       unsigned :0        /*airspace*/
       unsigned b:4       /*Store from the next unit*/
       unsigned c:4
};
  • Since the bit field is not allowed to span two bytes, the length of the bit field cannot be greater than the length of one byte, that is, it cannot exceed 8-bit binary.
  • A bit domain can be a Bitless domain name. At this time, it is only used for filling or adjusting the position. Nameless bit fields cannot be used. A bit field is essentially a structural type, but its members are allocated by binary.
struct k {
      int a:1
      int  :2          /*The 2 bits cannot be used*/
      int b:3
      int c:2
};

12.2.2 use of bit field

The use of bit field is the same as that of structure member. Its general form is:

Bit field variable nameĀ·Bit domain name

The bit field allows output in various formats.

#include <stdio.h>

struct bs {
    unsigned a: 1;
    unsigned b: 3;
    unsigned c: 4;
} bit, *pbit;

int main() {
    bit.a = 1;// The binary bit is 0000 0001, which only needs 1 bit of binary to save
    bit.b = 7;// The binary bit is 0000 0111, which can be saved only by 3 bits
    bit.c = 15;
    printf("%d,%d,%d\n", bit.a, bit.b, bit.c);// 1,7,15
    pbit = &bit;
    pbit->a = 0;
    pbit->b &= 3;
    pbit->c |= 1;
    printf("%d,%d,%d\n", pbit->a, pbit->b, pbit->c);// 0,3,15
}

Topics: C Back-end