服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - 谈谈C语言中位运算你要知道的那些事儿

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

2022-09-26 14:31Code_流苏 C/C++

C语言中的各种运算都是以字节的形式进行,在编写很多系统程序时,如驱动程序、磁盘文件管理程序等,常要求将数据按位(bit)进行运算或者处理,下面这篇文章主要给大家介绍了关于C语言中位运算的相关资料,需要的朋友可以参考下

一、概念说明

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位运算

以+为例

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

?
1
2
3
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.注释版

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
//编码及注释: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.纯源码版

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#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语言中位运算你要知道的那些事儿

总结

到此这篇关于C语言中位运算你要知道的那些事儿的文章就介绍到这了,更多相关C语言中的位运算内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/qq_51646682/article/details/122636328

延伸 · 阅读

精彩推荐
  • C/C++如何区分C++中的inline和#define宏

    如何区分C++中的inline和#define宏

    这篇文章主要介绍了如何区分C++中的inline和#define宏,文中讲解非常详细,代码帮助大家更好的参考和学习,感兴趣的朋友可以了解下...

    wywdahai4782021-09-09
  • C/C++C语言宏定义使用分析

    C语言宏定义使用分析

    在宏定义中,“宏名称”和“宏字符串”是通过“空格”来区分的,某些朋友不要混淆了,接下来请祥看本文...

    C语言中文网2242020-11-13
  • C/C++VScode上配置 c语言环境的图文教程

    VScode上配置 c语言环境的图文教程

    这篇文章主要介绍了配置VScode c语言环境,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以...

    成成赐我力量10842021-09-06
  • C/C++详解C++中的函数调用和下标以及成员访问运算符的重载

    详解C++中的函数调用和下标以及成员访问运算符的重载

    这篇文章主要介绍了详解C++中的函数调用和下标以及成员访问运算符,讲到了这些二元运算符使用的语法及重载,需要的朋友可以参考下...

    C++教程网12222021-03-23
  • C/C++opencv3/C++轮廓的提取与筛选方式

    opencv3/C++轮廓的提取与筛选方式

    今天小编就为大家分享一篇opencv3/C++轮廓的提取与筛选方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    阿卡蒂奥7012021-08-08
  • C/C++C++构造和解析Json的使用示例

    C++构造和解析Json的使用示例

    今天小编就为大家分享一篇关于C++构造和解析Json的使用示例,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来...

    蜗牛2017172021-07-14
  • C/C++C++实现归并排序(MergeSort)

    C++实现归并排序(MergeSort)

    这篇文章主要为大家详细介绍了C++实现归并排序,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    ChanJose11142021-09-01
  • C/C++C++中memset函数用法详解

    C++中memset函数用法详解

    这篇文章主要介绍了C++中memset函数用法,结合实例形式详细分析了memset函数的功能、使用方法与相关注意事项,需要的朋友可以参考下...

    雨竹9152021-04-07