Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What are the bit operators in C language programming development

2025-01-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article mainly explains "what are the bit operators in C language programming development". Interested friends may wish to take a look. The method introduced in this paper is simple, fast and practical. Let's let the editor take you to learn what are the bit operators in C language programming development.

In C language programming, the bit of data is the smallest data unit that can be operated. In theory, "bit operation" can be used to complete all operations and operations. The general bit operation is used to control the hardware, or to do data transformation, but flexible bit operation can effectively improve the efficiency of the program.

1. Bit operators in C language

Because C language is designed to replace assembly language, it must support the computing power of assembly language, so C language supports all bit operators (Bitwise Operators). Bit operation is to test, set or shift the bit (bit) in byte or word. In the programming of microprocessor, it is especially suitable to operate on register and Imax O port. Therefore, this section will introduce this in more detail.

The form and meaning of the six bit operators are as follows:

&: bitwise "and" (AND)

|: bitwise "OR" (OR)

^: bitwise XOR (XOR)

~: "reverse" (NOT)

": move data to the right

": data move to the left

1) bitwise "and" operation

The bitwise and operator & operates bitwise on the operands expressed in binary on both sides of the operator, respectively, in terms of the same bit (bit) in the number. The rule for the operation is that the output is 1 only if both operands are 1, otherwise 0.

For example:

A = 0x88 and b = 0x81, then the result of a & b is as follows:

0x88 1000 1000 a

& 0x81 1000 0001 b

= 1000 0000

Among them, the & operator makes 1 bit and 1 bit, 2 bits and 2 bits of a-number 0x88 and B-number 0x81. 7-bit and 7-bit "and" respectively. Because the operation rule of the "and" operation is that as long as one of the two operands is 0, the corresponding bit in the result is 0. In both an and b numbers, only the * bit (bit 7) is 1, so the result of this bit is 1, and the other results are 0.

Usually we can use the bitwise "and" operation & as a means to turn off a bit (that is, the position 0). For example, if we want to close the third bit in the a number without affecting the status quo of the other bits, we can use a number 0xF7, that is, the binary number 1111 0111, to perform a bitwise "and" operation with the a number:

0x88 1000 1000 a

& 0xF7 1111 0111 shielding number

= 1000 0000

Note that this number is 1 except the third bit is 0, and the result of the operation will only be the third position 0 in the a number, but the other bits of the a number will not be affected. In other words, if you need to close the nth bit of a number, you only need to phase that number with another number, and the other number is 1 except for the corresponding nth bit 0, so as to shield the other digits.

The above operation can be expressed as a = a & (0xF7) or a & = (0xF7). The functions of the two expressions are the same (see the "compound assignment operator" section of the previous section), but the second form is often seen in source code.

2) bitwise OR operation

The function of the bitwise OR operator | is to perform a bitwise OR operation on the operands expressed in binary on both sides of the operator, in units of the same bit (bit) in the number. The rule for the operation is that the output is 0 only if both operands are 0, otherwise it is 1.

For example:

A = 0x88 and b = 0x81, then the operation result of a | b is as follows:

0x88 1000 1000 a

| | number of 0x81 1000 0001 b |

= 1000 1001

Usually we can use the bitwise "and" operation & as a means of setting (that is, the position 1). For example, if we want to place the 0 and 1 position 1 in the a number without affecting the status quo of the other bits, we can use a number 0x03, that is, the binary number 00000011, to perform a bitwise OR operation with the a number:

0x88 1000 1000 a

| | number of shields for 0x03 0000 0011 |

= 1000 1011

Note that this number is 0 except for bit 0 and bit 1, and all others are 0. The result of the operation will only make position 0 and position 1 in a number 0, while other bits of a number will not be affected. In other words, if you need the nth position 1 of a number, you only need to phase the number with another number "OR", and the other number is 0 except the corresponding nth bit 1, so as to shield the others. The above operation can be expressed as a = a | (0xF7) or a | = (0xF7).

3) bitwise XOR operation

The bitwise XOR operator ^ performs a bitwise XOR operation on the binary operands on both sides of the operator, which is based on the same bit (bit) in the number. The rule for XOR operations is that only if the two operands are different, the corresponding output is 1, otherwise it is 0.

For example:

A = 0x88 and b = 0x81, then the result of a ^ b is as follows:

0x88 1000 1000 a

^ 0x81 1000 0001 shielding number

= 0000 1001

The bitwise XOR operation ^ has some special applications, which are introduced as follows:

① bitwise XOR operation can reverse specific bits.

For example, if we want to reverse the * * bits and * * bits in a number, we only need to use 0x81, that is, the binary number 10000001, to do a bitwise XOR operation with it, and the result is the same as above. After the operation, the value of the * bit has changed from 1 to 0, and the value of the bit has changed from 0 to 1, which has the effect of flipping the two bits. The state of the other bits remains the same.

As you can see, except for the * bit and the bit 1, all the other bits are 0. The result of the operation will only reverse the 0th and 7th bits of the a number, but the other bits of the a number will not be affected. In other words, if you need to invert the nth bit of a number, you only need to "XOR" the number with another number, and the other number is 0 except the corresponding nth bit 1, so as to shield the others. The above operation can be expressed as a = a ^ (0x81) or a ^ = (0x81).

② directly exchanges the values of two variables

For example, if you have a variable a = 3reb = 4 and you want to exchange their values, you can do the following set of operations:

A ^ = b

B ^ = a

A ^ = b

First, a ^ = b:

A 0000 0011

^ b 0000 0100

A = 0000 0111

Secondly, b ^ = a:

B 0000 0100

^ a 0000 0111

B = 0000 0011

* *, a ^ = b:

A 0000 0111

^ b 0000 0011

A = 0000 0100

In this way, the values in the two variables an and b are reversed.

4) "reverse" operation

The "take out" operator ~ is used to reverse the digits: all zeros are set to 1, and 1 is set to 0. For example:

The value of 1001 0110 is 0110 1001.

5) move the data to the right

The data move right operator moves each member of the variable to the right several bits as required. The common form of a right move statement is:

Number of variable "right shifts

For example, a = 1111 1100; after a = a "2 operation, a = 0011 000.

6) move the data to the left

The data move left operator moves each member of the variable several bits to the left as required. The common form of a left move statement is:

Variable "left shift

For example, a = 1111 0000; after a = a "2 operation, a = 1100 000.

Whether moving left or right, when a bit is moved out of one end, the white space at the other end will be supplemented by a 0 moved in from the outside (some computers are free 1, please refer to the corresponding C compiler user manual for details). This shows that the shift is different from the loop, the bits removed from one end are not sent back to the other end, the removed bits are lost forever, and only 0 of the corresponding digits can be added at the other end.

The shift operation can be used for fast multiplication and division of integers. Moving one bit to the left is equivalent to multiplying 2, while moving one bit to the right is equivalent to dividing by 2.

For example: X = 7, binary expression: 0000 0111

X "1 0000 1110, equivalent to: X = 2 / 7 / 14

X "3 0111 0000, which is equivalent to: x14, 2, 2, 112.

X "2 1100 0000, x = 192

In the third shift to the left, one of the displacements of 1 goes out, and the left can only be made up by 0, so it is not equal to 112'2'2 '448, but to 192. When x moves back according to the previous steps, it cannot return to the original value, because the one lost on the left can never be found again:

X "2 0011 0000, Xerox 48

X "3 0000 0110 x eight eight six

X "1 0000 0011 x two six three

The shift operation can also cooperate with other bit operators to set and detect each bit of the register or data I _ swap O interface, as shown in the next section.

two。 Introduction to some practical methods of bit operator

1) learn to apply compound operators

As described earlier, the bit operator can be combined with the assignment operator "=" to form a composite operator. That is, the following five:

"=," =, &, ^ =, | =

Where x "= y, which is equivalent to x = x" y

X "= y, equivalent to x = x" y

X & = y, equivalent to x = x & y

X ^ = y, equivalent to x = x ^ y

X | = y, equivalent to x = x | y

Learning to use compound operators in C language can simplify the source program and optimize the target program.

2) some common bit manipulation methods in C language.

Since the main purpose of learning C language here is to develop the control program of the microcontroller, we pay special attention to the operation statement of the register of MPU and the operation statement of a bit in IBO. If you want to assign, set 0, set 1, reverse, and test some bits of PORTA (port A), you may use statements such as the following:

① PORTA = 0x87

Assign a value to the entire PORTA to assign the number 1000 0111 to PORTA, that is, position 1 of PORTA 0, 1, 2, and 7, and clear 0 of the other bits.

② PORTA = (1 "7)

Assigning a value to the entire PORTA is equivalent to PORTA = 0x80, assigning the number 1000 0000 to PORTA, the specified seventh position 1, and the rest of the positions 0. It's just that there are two steps here, namely, the 1 "7 operation in parentheses, which means that the number 0x01 is moved 7 bits to the left, its value is changed to 0x80, and then it is assigned to PORTA.

③ PORTA = (1 "7) | (1" 3) | (1 "2)

Assign a value to the entire PORTA for the same effect as in ②, but to position 1 for 7, 3, and 2, respectively, and to set all other bits to 0. It first shifts the values given in the three parentheses, and then bitwise them, and * assigns the values to PORTA. That is:

1000 0000 (1 "7)

0000 1000 (1 "3)

| | 0000 0100 (1 "2) |

PORTA = 1000 1100

④ PORTA & = 0x80

Make the specified bit in PORTA clear 0, which is equivalent to PORTA = PORTA & (0x80). Because the binary expression of 0x80 is 1000 0000, taking advantage of its feature that the * * bit is 1 and all others are 0, as a template, the bits that are equal to 1 (such as bit 7 in this example) are shielded so that they remain the same, while the other bits are cleared 0 (whether it was 0 or 1). Because the bitwise "and" results of PORTA and 0x80 are as follows:

PORTA = 0x87 1000 0111

& 0x80 1000 0000

= 1000 0000

After the operation, the original value 1 of bit 7 is retained, and the other bits are cleared 0, of which the 3 bits of * * are all 0 now.

⑤ PORTA & (1 "7)

It is also equivalent to PORTA & = 0x80: it also includes two steps, that is, first perform the 1 "7 operation in parentheses, move 0x01 7 bits to the left, and its value becomes 0x80, and then do bitwise" and "with PORTA.

This operation clears each bit except the specified bit 7.

⑥ PORTA & = ~ (1 "7)

The instruction adds a reverse sign ~ after the equal sign. The difference with the previous operation is that before doing bitwise "and" with PORTA, the 0x80 is also reversed, converting 1000 0000 to 0111 1111, and then doing bitwise "and" operation. The result of this operation is that the specified bit 7 is cleared, and the rest of you remain the same.

⑦ PORTA | (1 "7)

Equivalent to PORTA = PORTA | (1 "7), also perform the 1" 7 operation in parentheses, move 0x01 7 bits to the left, its value becomes 0x80, and then do bitwise "OR" with PORTA.

If the initial value of PORTA before operation is 0x07, then:

PORTA 0000 0111

| | 0x80 1000 0000 |

PORTA = 1000 0111

This operation will leave position 1 and the rest of you unchanged.

It is important to note that this instruction is different from PORTA = (1 "7), although it can make a specified location 1. After PORTA = (1 "7) is executed, although one bit is set to 1, the other bits are modified, that is, no matter what the initial value of PORTA is, the original 1 bit will be overwritten by 0, and the result of execution is always 1000 0000. On the other hand, this instruction can mask other bits and do not change the state of other bits while changing the one to be set.

3) skillfully use the bit operation method in C language.

① will register the specified location 1 or clear 0

In practical applications, the instruction PORTA | = (1 "n) is often used to change any position 1 of the register without affecting the existing state of other bits. For example, if you want to change position 4 to 1, just use PORTA | = (1 "4). Of course, you can also use the PORTA | = (1 "7) | (1" 4) | (1 "0) instruction to set positions 8, 5, and 1 at a time, but does not affect the state of other bits.

In practical applications, the instruction PORTA & = ~ (1 "n) is often used to clear any bit of the register without affecting the existing state of other bits. For example, if you want to clear bit 4, just use PORTA & = ~ (1 "4).

When starting the nRF905 chip to send data to the air, the following functions are used:

Void nrf905_TxSend (void)

{

PORTD | = (1 "TRXCE)

DelayUs (1); / / > 10us

PORTD & = ~ (1 "TRXCE)

}

Among them, the one who controls the TRX_CE signal in the PORTD is first set to 1, and then cleared to output a high and a low pulse signal, which completes a data transmission in a pulse period. Because the TRX_CE signal is defined as the PD6 bit at the beginning of the program, that is, TRXCE = 6, the above two lines are equivalent to:

PORTD | (1 "6)

PORTD & = ~ (1 "6)

The ② test register refers to the state of location

In the process of receiving data, nRF905 should send out CD, AM and DR signals respectively, and MPU should also detect these bits to see if they become higher. If they become higher, execute the next step, otherwise they will jump out of the branch and return to the main program. Here is a section of the function that detects these bits:

Void nrf905_RxRecv (void)

{

While ((PIND& (1 "CD)) = = 0); / / CD pin 1, carrier signal detected

While ((PIND& (1 "AM)) = = 0); / / generally AM=1 indicates the address matching pair first

While ((PIND& (1 "DR)) = = 0); / / DR=1 indicates that the data is received correctly and the Crc is correct

/ / nrf905 has received data

Nrf905_ReadData (0); / / read the data in nrf905

}

Among them are:

While ((PIND& (1 "DR)) = = 0), or:

If ((PIND& (1 "DR)) = = 0); statement, whose function is to test the bits specified in the register.

In parentheses is an equation, which we separate to show what it does:

1 "DR:

DR has been defined as 2 at the beginning of the program, (1 "DR), that is, (1" 2), which means that the 0x01 is moved 2 bits to the left, resulting in 0000 0100

PIND& (1 "DR):

PIND is the value of the 8-bit pin of the PORTD port, and PIND& (1 "DR) means to phase it with (1" DR), that is, with 0000 0100. No matter what the other bits of PIND are, because they are equal to zero, the result of these bits is zero, and all we care about is the state of the second bit. Because this bit corresponds to 1, as long as the DR is high, there will be:

PIND xxx x1xx

& 0000 0100

Result = 0000 0100

The state of the second bit of the result is 1, that is, the entire expression (PIND& (1 "DR)) = = 0 is not valid, and the logical value of the statement is 0.

If DR is low, there are:

PIND xxxx x0xx

& 0000 0100

Result = 0000 0000

That is, the result of the entire expression is 0, (PIND& (1 "DR)) = = 0 holds, and the logical value of the statement is 1. Depending on the logical value in parentheses, the while or if statement determines the flow direction of the program.

At this point, I believe you have a deeper understanding of "what are the bit operators in C language programming development?" you might as well do it in practice. Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report