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

举报
CodeAllen 发表于 2021/10/30 01:35:02 2021/10/30
1.7k+ 0 0
【摘要】 知识来源主要是陈正冲老师的《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

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

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

循环移位:


      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

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

作者其他文章

评论(0

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

    全部回复

    上滑加载中

    设置昵称

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

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

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