目录
  • 一、概念说明
    • 1.概念
      • 1.1位运算
      • 1.2位运算符
    • 2.举例及补充
      • 2.1位运算
      • 2.2位运算符
  • 二、问题实战
    • 1.问题描述(开放题)
      • 2.输入输出
      • 三、源码实现(+详细注释)
        • 1.注释版
          • 2.纯源码版
          • 四、输出结果展示
            • 1.输出结果
            • 总结

              一、概念说明

              1.概念

              先来看一下位运算的概念:

              1.1位运算

              位运算简单来说,就是按二进制位进行运算。

              位运算: 从现代计算机中所有的数据二进制的形式存储在设备中。即 0、1 两种状态,计算机对二进制数据进行的运算(+、-、*、/)都是叫位运算,即将符号位共同参与运算的运算。

              了解了位运算之后,我们来看一下位运算符

              1.2位运算符

              符号 描述 运算规则
              & 按位与 两个位都为1时,结果才为1
              | 按位或 两个位都为0时,结果才为0
              ^ 按位异或 两个位相同为0,相异为1
              ~ 按位取反 0变1,1变0
              << 左移 各二进位全部左移若干位,高位去掉,低位补0
              >> 右移 各二进位全部右移若干位,对无符号数,高位补0,有符号数,编译器不同,处理方法不同

              关于右移:不同的编译器处理方法可能会不一样,有的会补符号位,有的会补0。

               ★小提示:
               a.逻辑位运算都是以 (bit)为单位。
               b.位运算符的操作数必须是整数/字符类型。

              2.举例及补充

              2.1位运算

              以+为例

              举一个简单的例子来看下( + – * \)位运算:

              int a = 3;
              int b = 4;
              int c = a + b;
              

              计算两个数的和,因为在计算机中都是以二进制来进行运算,所以上面我们所给的 int 变量会在机器内部先转换为二进制在进行相加:

              3(a): 0 0 0 0 0 0 1 1

              加上(+)

              4(b): 0 0 0 0 0 1 0 0

              等于(=)

              7(c ): 0 0 0 0 0 1 1 1

              通过观察我们可以发现,相比在代码中直接使用(+、-、*、/)运算符,如果有位运算符的话,代码运行效率会不会更高,随着位运算符后续的出现,发现其实确实是这样。

              下面一起来看一下位运算符:

              2.2位运算符

              关于每个运算符举一个简单的例子,来加深理解。

              2.2.1按位与“&”

              运算规则:
              0 & 0 = 0  
              0 & 1  =0  
              1 & 0 = 0  
              1 & 1 = 1
              简要口诀:(同1为1,其余为0)

              例如:

              3 & 5
              0000 0011(十进制:3)
              &
              0000 0101(十进制:5)
              =
              0000 0001 (十进制:1)

              因此结果等于1(十进制)

              2.2.2按位或“|”

              运算规则:0 | 0 = 0   
              0 | 1 = 1  
              1 | 0 = 1  
              1 | 1 = 1
              简要口诀:同0为0,其余为1

              例如:

              3 | 5
              0000 0011(十进制:3)
              |
              0000 0101(十进制:5)
              =
              0000 0111(十进制:7)

              因此结果等于7(十进制)

              2.2.3按位异或“^”

              运算规则:
              0 ^ 0 = 0  
              0 ^ 1 = 1  
              1 ^ 0 = 1  
              1 ^ 1 = 0
              简要口诀:相同为0,不同为1

              例如:

              4 ^ 7
              0000 0100(十进制:4)
              ^
              0000 0111 (十进制:7)
              =
              0000 0011(十进制:3)

              因此结果等于3(十进制)

              2.2.4按位非(取反)“~”

              运算规则:
              ~1 = 0  
              ~0 = 1
              简要口诀:1变0,0变1

              例如:

              ~15
              ~0000 1111(十进制:~15)
              =1111 0000(十进制:240)

              因此结果等于240(十进制)

              2.2.5左移“<<”

              补充:若左移时舍弃的高位不包含1,则每左移一位,相当于该数乘以2。

              例如:

              1 << 2
              即 1左移两位
              0000 0001(十进制:1)
              左移两位(<<2)后:
              0000 0100(十进制:4)

              结果为:4

              2.2.6右移“>>”

              补充: 操作数每右移一位,相当于该数除以2。

              例如:

              8 >> 2
              即 8右移两位
              0000 1000(十进制:8)
              右移两位( >>2 )后:
              0000 0010(十进制:2)

              结果为:2

              了解了这些概念之后,我们一起来看一下问题吧!

              二、问题实战

              自己编写了个题,仅用于学习,目的是为了加深对位运算的理解。

              大家可以尝试实现一下

              1.问题描述(开放题)

              Problem Description

              自己设计程序,要求用六种位运算符实现对两个整数的运算。

              2.输入输出

              Input

              Output

              两个整数经六种位运算分别得到的结果

              三、源码实现(+详细注释)

              1.注释版

              //编码及注释:Code_流苏
              //定义头文件
              #include<stdio.h>
              
              int main()
              {
              	//给定两个整数a和b 分别初始赋值为3和5
              	//定义d e f g h i分别存储各种位运算后的值
                  unsigned char a=3,b=5,c,d,e,f,g,h,i;
                  // a(3): 0000 0011
                  // b(5): 0000 0101 
                  
                  //按位与 &
                  c=a&b;
                  //经过按位与运算,得到c的值为0000 0001
                  //以十进制输出
                  printf("经过按位与运算后,可得c的值:%d\n",c);//输出结果为1
                  
                  //按位或 |
                  a=3;
                  b=5;
                  d=a|b;
                  //经过按位或运算,得到c的值为0000 0111
              	//以十进制输出
                  printf("经过按位或运算后,可得d的值:%d\n",d);//输出结果为7
                  
                  //按位异或 ^
                  a=3;
              	b=5;
              	e=a^b;
              	//经过按位异或运算,得到c的值为0000 0110
              	//以十进制输出
              	printf("经过按位异或运算后,可得e的值:%d\n",e);//输出结果为6
              	
              	//按位非(取反) ~
              	a=3;
              	b=7; //0000 0111 此处重新赋值 排除偶然性
              	f=~a;
              	g=~b;
              	//经过按位非(取反)运算,得到f的值为1111 1100 g的值为1111 1000
              	//以十进制输出
              	printf("经过按位非运算后,可得f和g的值:%d %d\n",f,g);//输出结果f的值为252,g的值为248
              	
              	//移位 左移:>> 右移:>>
              	a=3;
              	b=5;
              	h=a<<2;
              	i=b>>2;
              	//经过位移运算,得到f的值为0000 1100 g的值为0000 0001
              	//以十进制输出
              	printf("经过移位运算后,可得f和g的值:%d %d\n",h,i);//输出结果h的值为12,i的值为1
                  return 0;//返回0,代表程序执行结束
              }
              

              关于unsigned char的解释:

              unsigned char是无符号字节型,char类型变量的大小通常为1个字节(1字节=8个位),且属于整型。这就是为什么要用unsigned char的原因。

              2.纯源码版

              #include<stdio.h>
              #include<stdlib.h>
              
              int main()
              {
                  unsigned char a=3,b=5,c,d,e,f,g,h,i;
              
                  c=a&b;
                  printf("经过按位与运算后,可得c的值:%d\n",c);
                  
                  a=3;
                  b=5;
                  d=a|b;
                  printf("经过按位或运算后,可得d的值:%d\n",d);
                  
                  a=3;
              	b=5;
              	e=a^b;
              	printf("经过按位异或运算后,可得e的值:%d\n",e);
              	
              	a=3;
              	b=7; 
              	f=~a;
              	g=~b;
              	printf("经过按位非运算后,可得f和g的值:%d %d\n",f,g);
              	
              	a=3;
              	b=5;
              	h=a<<2;
              	i=b>>2;
              	printf("经过移位运算后,可得f和g的值:%d %d\n",h,i);
              	
                  return 0;
              }
              

              四、输出结果展示

              1.输出结果

              经过按位与运算后,可得c的值:1
              经过按位或运算后,可得d的值:7
              经过按位异或运算后,可得e的值:6
              经过按位非运算后,可得f和g的值:252 248
              经过移位运算后,可得f和g的值:12 1

              ——————————–
              Process exited after 0.3508 seconds with return value 0
              请按任意键继续. . .

              2.输出结果(图示版)

              谈谈C语言中位运算你要知道的那些事儿

              总结

              声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。