C语言学习第8篇---位运算符使用探究

举报
CodeAllen 发表于 2021/10/30 01:35:02 2021/10/30
【摘要】 知识来源主要是陈正冲老师的《C语言深度解剖》及Delphi Tang老师的《C语言剖析》,有兴趣的朋友可以看我置顶文章获取   很多新手都对位运算符理解的都不是很深刻,但是位运算在实际编程中使用的却很普遍,因为位运算是直接对bit的操作,效率最高。   与 & 计算取特定位   或 | ...

知识来源主要是陈正冲老师的《C语言深度解剖》及Delphi Tang老师的《C语言剖析》,有兴趣的朋友可以看我置顶文章获取

 

很多新手都对位运算符理解的都不是很深刻,但是位运算在实际编程中使用的却很普遍,因为位运算是直接对bit的操作,效率最高。

 

与 &

  1. 计算
  2. 取特定位

 

或 |

1.计算

2.要将某几位置一,就用与这几位是1的书进行  或


取反 ~

1.按位取反(变成二进制取反)


异或  ^

两个数不同时为1,否则为0 

1.使特定的位翻转,要将后七位翻转,就与后七位是1的数异或

2.在不使用临时变量的情况下实现俩个变量的互换

3.经常用在简单的加密算法上

 


左移  <<  双目运算符

左操作数必须为整型

  char 和 short 被隐式转换为int后进行移位操作

右操作数的范围必须为 :【0,31】

左移运算符<<将运算符的二进制位左移

  规则:高位丢弃,低位补0

右移运算符>>把运算符的二进制位右移

  规则:高位补符号位,低位丢弃

 

 

循环移位:


  
  1. left(unsigned value, int n)                                    /*自定义左移函数*/
  2. {
  3.     unsigned z;
  4.     z = (value >> (32-n)) | (value << n);                        /*循环左移的实现过程*/
  5.     return z;
  6. }

循环右移


  
  1. right(unsigned value, int n)                                    /*自定义右移函数*/
  2. {
  3.     unsigned z;
  4.     z = (value << (32-n)) | (value >> n);                        /*循环右移的实现过程*/
  5.     return z;
  6. }

 

位运算


  
  1. #include <stdio.h>
  2. int main()
  3. {
  4. printf("%d\n", 3 << 2);
  5. printf("%d\n", 3 >> 1);
  6. printf("%d\n", -1 >> 1);
  7. printf("%d\n", 0x01 << 2 + 3);
  8. printf("%d\n", 3 << -1); // oops!
  9. return 0;
  10. }

 

小提示:

防错的方法:

 ~避免位运算符,逻辑运算符和数学运算符同时出现在一个表达式中

  ~当位运算符,逻辑运算符合数学运算符需要同时参与运算符时,尽量使用括号()来表达计算次序

 

小技巧:

左移n位相当于乘以2的n次方,但效率比数学运算符高

右移n位相当于除以2的n次方,但效率比数学运算符高

 

实验2:交换两个整型变量的值


  
  1. #include <stdio.h>
  2. #define SWAP1(a, b) \
  3. { \
  4. int t = a; \
  5. a = b; \
  6. b = t; \
  7. }
  8. #define SWAP2(a, b) \
  9. { \
  10. a = a + b; \
  11. b = a - b; \
  12. a = a - b; \
  13. }
  14. #define SWAP3(a, b) \
  15. { \
  16. a = a ^ b; \
  17. b = a ^ b; \
  18. a = a ^ b; \
  19. }
  20. int main()
  21. {
  22. int a = 1;
  23. int b = 2;
  24. printf("a = %d\n", a);
  25. printf("b = %d\n", b);
  26. SWAP3(a ,b);
  27. printf("a = %d\n", a);
  28. printf("b = %d\n", b);
  29. return 0;
  30. }

 

实验三:混淆概念的判断条件


  
  1. #include <stdio.h>
  2. int main()
  3. {
  4. int i = 0;
  5. int j = 0;
  6. int k = 0;
  7. if( ++i | ++j & ++k )
  8. {
  9. printf("Run here...\n");
  10. }
  11. return 0;
  12. }

 

位段

位段类型是一种特殊的结构类型,其所有成员的长度均是以二进制位为单位定义的,结构中的成员被称为位段。位段定义的一般形式为:

 

结构 结构名

{

 类型 变量名1:长度;

 类型 变量名2:长度;

 ……

 类型 变量名n:长度;

}

 

  一个位段必须被说明是int、unsigned或signed中的一种


  
  1. 循环移动例子:
  2. #include <stdio.h>
  3. left(unsigned value, int n)                                    /*自定义左移函数*/
  4. {
  5.     unsigned z;
  6.     z = (value >> (32-n)) | (value << n);                        /*循环左移的实现过程*/ 
  7.    return z;
  8. }
  9. right(unsigned value, int n)                                    /*自定义右移函数*/
  10. {
  11.     unsigned z;
  12.     z = (value << (32-n)) | (value >> n);                        /*循环右移的实现过程*/
  13.     return z;
  14. }
  15. main()
  16. {
  17.     unsigned a;
  18.     int n;
  19.     printf("please input a number:\n");
  20.     scanf("%o", &a);                                        /*输入一个八进制数*/
  21.     printf("please input the number of displacement(>0):\n");
  22.     scanf("%d", &n);                                    /*输入要移位的位数*/
  23.     printf("the result is %o:\n", left(a, n));                    /*将左移后的结果输出*/
  24.     printf("the result is %o:\n", right(a, n));                    /*将右移后的结果输出*/
  25. }

 

 

 

运算符总结:

算数运算符:

+   -   *   /    %(取余数)

 

 

关系运算符

>     >=    <      <=      !=(不等于)        =(等于)

 

 

逻辑运算符

!       &&(并且)      ||(或)

 

 

C语言对真假判断:非零是真

                                零是假

 

&&左边的表达式为假,右边的肯定是不会执行的

||   左边的表达式为真   ,右边的表达式肯定不会执行

 

赋值运算符:

=      +=       *=             /=           -=

 

优先级别:    算数>关系>逻辑>赋值

 

 

文章来源: allen5g.blog.csdn.net,作者:CodeAllen的博客,版权归原作者所有,如需转载,请联系作者。

原文链接:allen5g.blog.csdn.net/article/details/78848658

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。