位运算
按位与 (&)
- 定义:(X)i=1并且(Y)i=1,则(X&Y)=1,否则为0
- 作用:使某一位或几位为0;取一个数中的一段
#include<stdio.h>
void _din(int number)//输出一个十进制数的二进制形式
{
unsigned int mask=1u<<31;
while(mask){
printf("%d",number&mask?1:0);
mask>>=1;
}
printf("\n");
}
int main()
{
int a=15;
int b=562;
int c=a&b;
_din(a);//00000000000000000000000000001111
_din(b);//00000000000000000000001000110010
_din(c);//00000000000000000000000000000010
return 0;
}
按位或 (|)
- 定义:(X)i=1或(Y)i=1,则(X|Y)=1
- 作用:使某几位或一位为1;把两个数拼起来
#include<stdio.h>
void _din(int number)//输出一个十进制数的二进制形式
{
unsigned int mask=1u<<31;
while(mask){
printf("%d",number&mask?1:0);
mask>>=1;
}
printf("\n");
}
int main()
{
int a=15;
int b=562;
int c=a|b;
_din(a);//00000000000000000000000000001111
_din(b);//00000000000000000000001000110010
_din(c);//00000000000000000000001000111111
return 0;
}
按位取反 (~)
- 定义:(取反Xi)=1-(X)i
- 作用:取反0等价于全为1;x|7使x的低三位为1,x|(~0)使低三位为0
#include<stdio.h>
void _din(int number)//输出一个十进制数的二进制形式
{
unsigned int mask=1u<<31;
while(mask){
printf("%d",number&mask?1:0);
mask>>=1;
}
printf("\n");
}
int main()
{
int number=13;
int a=7;
_din(a); //00000000000000000000000000000111
_din(number); //00000000000000000000000000001101
_din(number|a); //00000000000000000000000000001111
_din(number&(~a)); //00000000000000000000000000001000
return 0;
}
按位异或 (^)
-
定义:(X)i==(Y)i 则(X^Y)i=0, 否则为1;
-
作用:X异或Y异或Y=X
#include<stdio.h>
void _din(int number)//输出一个十进制数的二进制形式
{
unsigned int mask=1u<<31;
while(mask){
printf("%d",number&mask?1:0);
mask>>=1;
}
printf("\n");
}
int main()
{
int number=13;
int a=7;
_din(a); //00000000000000000000000000000111
_din(number); //00000000000000000000000000001101
_din(number^a); //00000000000000000000000000001010
_din(number^a^a); //00000000000000000000000000001101
return 0;
}
按位左移 (i<<j)
- 定义:i中所有位左移j,右边补0
- 作用:x<<1等价于x=x/2;
#include<stdio.h>
void _din(int number)//输出一个十进制数的二进制形式
{
unsigned int mask=1u<<31;
while(mask){
printf("%d",number&mask?1:0);
mask>>=1;
}
printf("\n");
}
int main()
{
int number=13;
_din(number); //00000000000000000000000000001101
_din(number<<1); //00000000000000000000000000011010
printf("%d\n",number<<1); //26
printf("%d",number*2); //26
return 0;
}
按位右移 (i>>j)
- 定义:i中所有位右移j。当i为unsigned时左补0;当i为signed时,有负号补1,否则补0
- 作用:i>>1等价于i=i/2;
#include<stdio.h>
void _din(int number)//输出一个十进制数的二进制形式
{
unsigned int mask=1u<<31;
while(mask){
printf("%d",number&mask?1:0);
mask>>=1;
}
printf("\n");
}
int main()
{
int number=-12;
_din(number); //11111111111111111111111111110100
_din(number>>1); //11111111111111111111111111111010
printf("%d\n",number>>1); //-6
printf("%d\n",number/2); //-6
unsigned int unumber=12;
_din(unumber); //00000000000000000000000000001100
_din(unumber>>1); //00000000000000000000000000000110
printf("%d\n",unumber>>1); //6
printf("%d",unumber/2); //6
return 0;
}
按位运算在单片机中使用场景
单个位控制
假设:寄存器地址为UOLCK(8位),SBS在右数第2位(1为开,0为关),PE在右数第3位(1为开,0为关)
#include<stdio.h>
#define uint8 unsigned char
void _din(uint8 number)//输出一个char的二进制形式
{
uint8 mask=1u<<7;
while(mask){
printf("%d",number&mask?1:0);
mask>>=1;
}
printf("\n");
}
int main()
{
uint8 UOLCK=0;
const uint8 SBS=(1u<<1);
const uint8 PE=(1u<<2);
_din(SBS); //00000010
_din(PE); //00000100
//打开SBS
_din(UOLCK|=SBS); //00000010
//关闭SBS
_din(UOLCK&=~SBS); //00000000
//同时打开SBS与PE
_din(UOLCK|=(SBS|PE)); //00000110
//同时关闭SBS与PE
_din(UOLCK&=~(SBS|PE)); //00000000
return 0;
}
多位操作
假设:寄存器地址为UOLCK(8位),AB占右数第4、5位(共有四种状态00、01、10、11),PE在右数第3位(1为开,0为关),SBS在右数第2位(1为开,0为关)
#include<stdio.h>
#define uint8 unsigned char
void _din(uint8 number)//输出一个char的二进制形式
{
uint8 mask=1u<<7;
while(mask){
printf("%d",number&mask?1:0);
mask>>=1;
}
printf("\n");
}
typedef struct{
uint8 flag1:1;
uint8 SBS:1;
uint8 PE:1;
uint8 AB:2;
uint8 flag2:3;
}Register;
int main()
{
Register uolck={.flag1=0,.flag2=0};
uolck.SBS=0;
uolck.PE=1;
uolck.AB=3;
_din(*((uint8*)&uolck)); //00011100
return 0;
}