C语言 位运算及在单片机上使用方法

位运算

按位与 (&)

  • 定义:(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;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值