说明:
本文原创作者『Allen5G』
首发于微信公众号『Allen5G』,同时也更新在我的:CSDN,简书
标签:嵌入式软件,算法,架构
很多新手都对位运算符理解的都不是很深刻,但是位运算在实际编程中使用的却很普遍,因为位运算是直接对bit的操作,效率最高。
与 &
- 计算
- 取特定位
或 |
1.计算
2.要将某几位置一,就用与这几位是1的书进行 或
取反 ~
1.按位取反(变成二进制取反)
异或 ^
两个数不同时为1,否则为0
1.使特定的位翻转,要将后七位翻转,就与后七位是1的数异或
2.在不使用临时变量的情况下实现俩个变量的互换
3.经常用在简单的加密算法上
左移 << 双目运算符
左操作数必须为整型
char 和 short 被隐式转换为int后进行移位操作
右操作数的范围必须为 :【0,31】
左移运算符<<将运算符的二进制位左移
规则:高位丢弃,低位补0
右移运算符>>把运算符的二进制位右移
规则:高位补符号位,低位丢弃
循环移位:
left(unsigned value, int n) /*自定义左移函数*/
{
unsigned z;
z = (value >> (32-n)) | (value << n); /*循环左移的实现过程*/
return z;
}
image.gif
循环右移
right(unsigned value, int n) /*自定义右移函数*/
{
unsigned z;
z = (value << (32-n)) | (value >> n); /*循环右移的实现过程*/
return z;
}
image.gif
位运算
#include <stdio.h>
int main()
{
printf("%d\n", 3 << 2);
printf("%d\n", 3 >> 1);
printf("%d\n", -1 >> 1);
printf("%d\n", 0x01 << 2 + 3);
printf("%d\n", 3 << -1); // oops!
return 0;
}
image.gif
小提示:
防错的方法:
~避免位运算符,逻辑运算符和数学运算符同时出现在一个表达式中
~当位运算符,逻辑运算符合数学运算符需要同时参与运算符时,尽量使用括号()来表达计算次序
小技巧:
左移n位相当于乘以2的n次方,但效率比数学运算符高
右移n位相当于除以2的n次方,但效率比数学运算符高
实验2:交换两个整型变量的值
#include <stdio.h>
#define SWAP1(a, b) \
{ \
int t = a; \
a = b; \
b = t; \
}
#define SWAP2(a, b) \
{ \
a = a + b; \
b = a - b; \
a = a - b; \
}
#define SWAP3(a, b) \
{ \
a = a ^ b; \
b = a ^ b; \
a = a ^ b; \
}
int main()
{
int a = 1;
int b = 2;
printf("a = %d\n", a);
printf("b = %d\n", b);
SWAP3(a ,b);
printf("a = %d\n", a);
printf("b = %d\n", b);
return 0;
}
image.gif
实验三:混淆概念的判断条件
#include <stdio.h>
int main()
{
int i = 0;
int j = 0;
int k = 0;
if( ++i | ++j & ++k )
{
printf("Run here...\n");
}
return 0;
}
image.gif
位段
位段类型是一种特殊的结构类型,其所有成员的长度均是以二进制位为单位定义的,结构中的成员被称为位段。位段定义的一般形式为:
结构 结构名
{
类型 变量名1:长度;
类型 变量名2:长度;
……
类型 变量名n:长度;
}
一个位段必须被说明是int、unsigned或signed中的一种
循环移动例子:
#include <stdio.h>
left(unsigned value, int n) /*自定义左移函数*/
{
unsigned z;
z = (value >> (32-n)) | (value << n); /*循环左移的实现过程*/
return z;
}
right(unsigned value, int n) /*自定义右移函数*/
{
unsigned z;
z = (value << (32-n)) | (value >> n); /*循环右移的实现过程*/
return z;
}
main()
{
unsigned a;
int n;
printf("please input a number:\n");
scanf("%o", &a); /*输入一个八进制数*/
printf("please input the number of displacement(>0):\n");
scanf("%d", &n); /*输入要移位的位数*/
printf("the result is %o:\n", left(a, n)); /*将左移后的结果输出*/
printf("the result is %o:\n", right(a, n)); /*将右移后的结果输出*/
}
image.gif
运算符总结:
算数运算符:
+ - * / %(取余数)
关系运算符
> >= < <= !=(不等于) =(等于)
逻辑运算符
! &&(并且) ||(或)
C语言对真假判断:非零是真
零是假
&&左边的表达式为假,右边的肯定是不会执行的
|| 左边的表达式为真 ,右边的表达式肯定不会执行
赋值运算符:
= += *= /= -=
优先级别: 算数>关系>逻辑>赋值
说明
1.该文档仅供个人学习使用,版权所有,禁止商用。
2.本文由我一个人编辑并整理,难免存在一些错误。
3.为了方便大家平时公交、地铁、外出办事也能用手机随时随地查看该教程,该教程同步更新于微信公众号『Allen5G』。
关于我
我的博客:https://blog.csdn.net/super828
我的GitHub:https://github.com/lkk789
我的微信公众号(ID:Allen5G)主要分享软件工程师进阶(嵌入式,Linux,C/C++,python,英语),程序员职业发展,如果想查看更多内容,可以关注我的微信公众号『Allen5G』。
我是Allen,世界500强外企通信软件工程师,每天分享编程,算法,软件进阶知识。欢迎关注我的公众号「Allen5G」,回复「1024」获取最新最全的技术资料,还可以进入技术交流群获取经验方法。
网友评论