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

目录
  • 一、概念说明
    • 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语言中位运算你要知道的那些事儿的文章就介绍到这了,更多相关C语言中的位运算内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • c语言中用位运算实现加法技巧介绍

    用位运算实现加法也就是计算机用二进制进行运算,32位的CPU只能表示32位内的数,这里先用1位数的加法来进行,在不考虑进位的基础上,如下 复制代码 代码如下: 1 + 1 = 0 1 + 0 = 1 0 + 1 = 1 0 + 0 = 0 很明显这几个表达式可以用位运算的"^"来代替,如下 复制代码 代码如下: 1 ^ 1 = 0 1 ^ 0 = 1 0 ^ 1 = 1 0 ^ 0 = 0 这样我们就完成了简单的一位数加法,那么要进行二位的加法,这个方法可行不可行呢?肯定是不行的,矛盾

  • C语言 位运算详解及示例代码

    所谓位运算,就是对一个比特(Bit)位进行操作.在<二进制思想以及数据的存储>一节中讲到,比特(Bit)是一个电子元器件,8个比特构成一个字节(Byte),它已经是粒度最小的可操作单元了. C语言提供了六种位运算符: 运算符 & | ^ ~ << >> 说明 按位与 按位或 按位异或 取反 左移 右移 按位与运算(&) 一个比特(Bit)位只有 0 和 1 两个取值,只有参与&运算的两个位都为 1 时,结果才为 1,否则为 0.例如1&1

  • 图文详解C语言位运算基础知识

    C语言位运算基础知识分享给大家,希望对大家有帮助. 1.   程序中的所有数在计算机内存中都是以二进制的形式储存的.位运算说穿了,就是直接对整数在内存中的二进制位进行操作. 2.  与运算:只有前后两个运算数都是 1 的时候结果才是1. 3.  或运算:有1位为1,结果便为1. 4.  异或:不相同则为1. 5.  取反运算:将1变为0,将0变为1. 6.  移位运算:左移则乘2,右移则除2.如果超出边界,则舍弃. 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们.

  • C语言位运算和sizeof运算符详解

    位运算和sizeof运算符 C语言中提供了一些运算符可以直接操作整数的位,称为位运算,因此位运算中的操作数都必须是整型的.位运算的效率是比较高的,而且位运算运用好的话会达到意想不到的效果.位运算主要有6种:与(&),或(|),取反(~),异或(^),左移(<<),右移(>>). 1.位运算中的类型转换 位运算都必须进行Integer Promotion.在进行运算之前,都必须将char型.short型的数据转换为int或者unsigned int型再参与运算. 如下面这段程

  • C语言位运算符:与、或、异或、取反、左移与右移详细介绍

    位运算是指按二进制进行的运算.在系统软件中,常常需要处理二进制位的问题.C语言提供了6个位操作运算符.这些运算符只能用于整型操作数,即只能用于带符号或无符号的char,short,int与long类型. C语言提供的位运算符列表:运算符 含义 描述& 按位与 如果两个相应的二进制位都为1,则该位的结果值为1,否则为0| 按位或 两个相应的二进制位中只要有一个为1,该位的结果值为1^ 按位异或 若参加运算的两个二进制位值相同则为0,否则为1~ 取反 ~是一元运算符,用来对一个二进制数按位取反,即将

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

    目录 一.概念说明 1.概念 1.1位运算 1.2位运算符 2.举例及补充 2.1位运算 2.2位运算符 二.问题实战 1.问题描述(开放题) 2.输入输出 三.源码实现(+详细注释) 1.注释版 2.纯源码版 四.输出结果展示 1.输出结果 总结 一.概念说明 1.概念 先来看一下位运算的概念: 1.1位运算 位运算简单来说,就是按二进制位进行运算. 位运算: 从现代计算机中所有的数据二进制的形式存储在设备中.即 0.1 两种状态,计算机对二进制数据进行的运算(+.-.*./)都是叫位运算,即

  • C语言中各种运算类型全面总结

    目录 一.概述 二.四则运算 三.关系运算 四.逻辑运算与位运算 五.深度剖析位运算 一.概述 C语言中支持下面4种类型的运算 运算类型 运算符 四则运算 +,-,*,/,% 关系运算 <,>,<=,>=,==,!= 逻辑运算 &&,||,! 位运算 &,|,^,>>,<<,~ 二.四则运算 (+,-,*,/,%) 就是数学中的加,减,乘,除等运算 遵循先乘除后加减的运算优先级 可以使用括号改变运算顺序 注意: C语言中的除法运算,其

  • 详解Python中位运算的简单实现

    目录 简介 应用场景 案例源码 简介 程序中的数在计算机内存中都是以二进制的形式存在的,位运算就是直接对整数在内存中对应的二进制位进行操作,一般是将数字化为二进制数后进行操作. 应用场景 在常规操作和位运算的操作中使用位运算,可以提升性能.但是会造成代码难以理解,建议合理利用. 1.统计奇数 2.统计偶数 3.统计不相同数等 4.求相反数 位运算分有6种: 1.按位与:两个位都为1时,结果才为1(统计奇数)即全1为1. 2.按位或:两个位都为0时,结果才为0(统计偶数)即全0为0. 3.按位异或

  • 解析C语言中位字段内存分配的问题

    C语言的位字段是个比较有意思的特性.它的目的是在一个机器字中保存多个对象(每个对象占据若干bit),从而节省内存资源,同时又避免复杂的位运算.在此不再讨论位字段的具体语法,下面将研究位字段的存储特性. 先说含有多个字段(field)的字(word)所占空间的规律--含有多个字段的字的大小是所有字段的类型中的最长的那个的倍数.但要确定究竟是最长类型的几倍则比较复杂,这要看是否需要考虑类型对齐问题(即一个字段能否跨越两个最长类型). 例1: struct word {char  field1 : 1

  • js中位运算的运用实例分析

    我们可能很少在编程中用位运算,如果没深入学习,可能也很难理解.平时的数值运算,其实是要先转换成二进制再进行运算的,而位运算就是直接进行二进制运算,所以位运算的执行效率肯定是更高的.下面通过一些实例来加深对位运算的理解. 按位与(&) &&运算符我们都知道,只有两个都为真,结果才为真.&道理是一样的,只有两个数的值为1时,才返回1.例如1和3的按位与操作: 0001 &  0011   ---------     0001 只有对应的数为1时,结果才为1,其他都为0.

  • 简单谈谈C语言中的= 和==、!=

    1. =: 在C语言中等号(=)为赋值操作符,下面进行简单说明赋值操作符的使用 1) 变量的赋值操作: int a; a = 10; 此处为将10赋值给a,赋值过后a的值为10 2) 指针变量的赋值操作:(分别为 取地址的赋值和指针变量的赋值) 第一种: int arr[999] = { 0 }; int *p = NULL; p = (int *)&arr; 定义一个int(整形)的变量arr,并且将arr的数组中的每个数组元素初始化为0 定义一个int(整形)的指针变量p,并且初始化为NUL

  • 详细谈谈C语言中动态内存

    目录 前言 1.关于动态内存的函数 1.1malloc和free函数 1.2calloc函数 1.3realloc函数 2.常见的动态内存错误 2.1对NULL指针解引用 2.2对动态内存开辟的空间越界访问 2.3 对非动态开辟内存使用free释放 2.4 使用free释放一块动态开辟内存的一部分 2.5对同一块动态内存多次释放 2.6内存泄漏 补充:为什么要引入动态内存分配 总结 前言 关于动态内存管理,可能有学习过的小伙伴,也有没有听说过的.没有听说过的小伙伴会觉得很奇怪啊,为什么要动态开辟

  • c语言中位字段与结构联合的组合使用详解

    举例:=================================================== 复制代码 代码如下: /** INITRM - Initialization of internal ram position register; 0x0000 0010 **/ typedef union { byte Byte; struct { byte RAMHAL :1; byte :1; byte :1; byte RAM11 :1; byte RAM12 :1; byte

  • Java中位运算(移位、位与、或、异或、非) 的简单实例

    复制代码 代码如下: public class Test {     public static void main(String[] args) {         // 1.左移( << )         // 0000 0000 0000 0000 0000 0000 0000 0101 然后左移2位后,低位补0://         // 0000 0000 0000 0000 0000 0000 0001 0100 换算成10进制为20         System.out.pri

随机推荐