C语言学习第8篇---位运算符使用探究
知识来源主要是陈正冲老师的《C语言深度解剖》及Delphi Tang老师的《C语言剖析》,有兴趣的朋友可以看我置顶文章获取
很多新手都对位运算符理解的都不是很深刻,但是位运算在实际编程中使用的却很普遍,因为位运算是直接对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;
-
-
}
循环右移
-
right(unsigned value, int n) /*自定义右移函数*/
-
-
{
-
-
unsigned z;
-
-
z = (value << (32-n)) | (value >> n); /*循环右移的实现过程*/
-
-
return z;
-
-
}
位运算
-
#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;
-
}
小提示:
防错的方法:
~避免位运算符,逻辑运算符和数学运算符同时出现在一个表达式中
~当位运算符,逻辑运算符合数学运算符需要同时参与运算符时,尽量使用括号()来表达计算次序
小技巧:
左移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;
-
}
实验三:混淆概念的判断条件
-
#include <stdio.h>
-
int main()
-
{
-
int i = 0;
-
int j = 0;
-
int k = 0;
-
-
if( ++i | ++j & ++k )
-
{
-
printf("Run here...\n");
-
}
-
-
return 0;
-
}
位段
位段类型是一种特殊的结构类型,其所有成员的长度均是以二进制位为单位定义的,结构中的成员被称为位段。位段定义的一般形式为:
结构 结构名
{
类型 变量名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)); /*将右移后的结果输出*/
-
-
}
运算符总结:
算数运算符:
+ - * / %(取余数)
关系运算符
> >= < <= !=(不等于) =(等于)
逻辑运算符
! &&(并且) ||(或)
C语言对真假判断:非零是真
零是假
&&左边的表达式为假,右边的肯定是不会执行的
|| 左边的表达式为真 ,右边的表达式肯定不会执行
赋值运算符:
= += *= /= -=
优先级别: 算数>关系>逻辑>赋值
文章来源: allen5g.blog.csdn.net,作者:CodeAllen的博客,版权归原作者所有,如需转载,请联系作者。
原文链接:allen5g.blog.csdn.net/article/details/78848658
- 点赞
- 收藏
- 关注作者
评论(0)