【C语言】移位操作符 位操作符 - 对二进制位进行精准操作【+面试题目】_[初阶篇]
创始人
2024-01-16 21:34:52
0

快速导航

【前言】

1.移位操作符

1.1左移操作符(<<)

1.2右移操作符(>>)

2.位操作符

2.1 & 按位与

2.2  | (按位或) 

2.3  ^ (按位异或)

3.面试题目

3.1 交换两个变量(不创建临时变量)

3.2统计二进制中1的个数 

3.2.1 方法一:右移(>>)和按位与(&)

3.2.2 方法二:使用取余操作符(%)

3.2.3 方法三:借助num&(num-1)​​​​​​​

【前言】

相信有很多人对移位操作符和位操作符并不是很理解,没有关系,认真读完本篇文章,你对C操作符的理解会上升到一个新高度。

虽然说本篇文章是初阶篇,但是文章内容并不简单,操作的时候涉及到二进制位,那我们就先来看一看何为二进制位?

二进制位简称“位”,是二进制记数系统中表示小于2的整数的符号,一般用1或 0表示,是具有相等概率的两种状态中的一种。

二进制位的位数可表示一个机器字的字长,一个二进制位包含的信息量称为 - 比特。

1.移位操作符

移位操作符有两种:一种是左移操作符(<<),另一种是右移操作符(>>)

这两种操作符都是对整数在存储在电脑中的二进制位进行操作(注意:移位操作符的操作数必须是整数)。

1.1左移操作符(<<)

接下来我们借助一个整数来更好的理解和应用左移操作符:

 watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAQ2F0enp6NjY2,size_18,color_FFFFFF,t_70,g_se,x_16

在计算机内存中存储的是二进制形式的补码,而正数的原码,反码,补码相同,5在内存中的补码:

 watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAQ2F0enp6NjY2,size_19,color_FFFFFF,t_70,g_se,x_16

移位操作符,移动的是二进制位,因为整数在内存中存储的是补码,所以移动的是内存中存储的补码 。

补码我们已经给出,接下来看一看移位操作符到底是怎么进行移位呢?

左移操作符移位原则:左边抛弃,右边补0。

#include int main()
{int a = 5;printf("%d\n", a << 1);return 0;
}

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAQ2F0enp6NjY2,size_20,color_FFFFFF,t_70,g_se,x_16

5左移之后结果为10,看似是有乘2的效果的,那么是不是这样的呢?

下面我们来多举几个栗子验证一下。

#include 
int main()
{int a = -1;printf("%d\n", a << 1);a = -10;printf("%d\n", a << 1);a = 100;printf("%d\n", a << 1);return 0;
}

负数左移的效果也是一样的(以-1为例):

结论:左移操作符确实有乘2的效果。  

练习使用一下左移操作符:

原题链接:2的n次方计算_牛客题霸_牛客网 

题目描述:不使用累加法的基础上,使用左移操作符(<<) 完成2的n次方的计算。

 代码实现

#include int main()
{int n = 0;scanf("%d", &n);printf("%d\n", 1 << n);return 0;
}

1.2右移操作符(>>)

右移操作符和左移操作符是相似的,右移操作符和左移操作符最大的区别是在右移之后:

1.左边补符号位(算术右移)

2.左边补0(逻辑右移)

究竟是哪一种取决于程序的运行环境,不同编译器下右移方式可以不同。

int main()
{int a = -1;printf("%d\n", a >> 1);return 0;
}

上面是VS2019下的运行结果,VS2019支持的是算术右移。 

 注意:移位操作符,不要移动负数位,这是标准未定义的;

​​​​​​​对比一下左移操作符乘2效果,右移操作符是否具有除2的效果呢?

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAQ2F0enp6NjY2,size_20,color_FFFFFF,t_70,g_se,x_16

对于正数来说,可以认为具有除2的效果,但是不要忘了负数;我们在上面举例的-1右移之后还是-1,就不满足了。 

所以不能直接说右移操作符具有除2的效果。​​​​​​​

2.位操作符

位操作符,是对一个数的二进制位进行操作,两个操作数,且操作数必须是整数。

具体分为三种:& (按位与)     |(按位或)     ^(按位异或)。计算机中位运算操作,均是以二进制补码形式进行的

2.1 & 按位与

两个数的二进制相同位同为1时结果为1,否则为0。

下面看一下使用按位与(&)操作的两种情况 :

2.2  | (按位或) 

 两个数的相同二进制位同为0时结果为0,否则为1。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAQ2F0enp6NjY2,size_20,color_FFFFFF,t_70,g_se,x_16

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAQ2F0enp6NjY2,size_20,color_FFFFFF,t_70,g_se,x_16

2.3  ^ (按位异或)

两个数相同二进制位相异时为1,相同是为0。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAQ2F0enp6NjY2,size_20,color_FFFFFF,t_70,g_se,x_16 watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAQ2F0enp6NjY2,size_20,color_FFFFFF,t_70,g_se,x_16

3.面试题目

3.1 交换两个变量(不创建临时变量)

在交换两个变量时,我们经常会借助第三个变量tmp;

比如交换a和b的值:

int tmp = a;

a = b;

b = tmp;//那么不创建临时变量的话我们怎么来交换两个变量呢?

使用异或操作符(^),异或的两个特征:0^num = num;num^ num = 0;

 代码实现

int main()
{int a = 10;int b = 20;printf("a=%d, b=%d\n", a, b);a = a ^ b;b = a ^ b;//b修改为aa = a ^ b;//a修改为bprintf("a=%d, b=%d\n", a, b);return 0;
}

缺陷:因为按位异或操作符的操作数只能是整数,所以交换的两个变量也必须是整数,只能完成两个整数的交换,无法完成两个浮点数的交换。 

3.2统计二进制中1的个数 

3.2.1 方法一:右移(>>)和按位与(&)

代码实现:

int getBinaryCount(int num)
{int count = 0;//记录二进制中1的个数int i = 0;for (i = 0; i < 32; i++){if (((num >> i) & 1) == 1){count++;}}return count;
}

3.2.2 方法二:使用取余操作符(%)

一个十进制的数,想要获取它的每一位,需要进行%10、/10;二进制的数也是一样的,可以通过%2、/2来获取每一位。

代码实现 

int getBinaryCount(unsigned int num)
{int count = 0;while (num){if(num % 2 == 1)count++;num /= 2;}return count;
}

这里解释一下为什么要传入unsigned int类型:使用负数举例,如果num是-1的话,进入循环一次之后除2就变为0,无法得到二进制中1的正确个数;

使用unsigned int的话会把-1的补码当成一个正数的补码,这是一个很大的数,可以进行以上操作。

3.2.3 方法三:借助num&(num-1)

代码实现 

int getBinaryCount(int num)
{int count = 0;while (num){num &= num - 1;count++;}return count;
}

上一篇:【MLOPs】Docker

下一篇:爸爸修理长城

相关内容

热门资讯

大觉山概况导游词 大觉山概况导游词  大觉山是资溪县首屈一指的游览胜地。俗话说:“大觉山水冠武夷,武夷山水大觉奇。”大...
香港会议展览中心的导游词 香港会议展览中心的导游词  位于湾仔博览道1号的香港会议展览中心,是该区最新建筑群中的代表者之一。除...
央迈勇导游讲解词 央迈勇导游讲解词  央迈勇藏语意为:“文殊菩萨”为“三怙主”雪山的南峰,海拔高度为5958米,在佛教...
乌石塘导游词 乌石塘导游词  各位游客大家好!我叫周一佳,大家可以叫我周导游。今天由我来带大家一块儿旅行,希望大家...
江门东湖公园导游词 江门东湖公园导游词  作为一位出色的导游人员,很有必要精心设计一份导游词,导游词具有形象、生动、具有...
苏州经典导游词 苏州经典导游词  作为一位尽职的导游,常常要根据讲解需要编写导游词,导游词可以帮助旅游者欣赏景观,以...
原创导游词巴人之迷详解 原创导游词巴人之迷详解  巴人之谜:剑  从公元前十六世纪开始,巴人已在三峡地区频繁活动。他们在长江...
福建南靖土楼导游词 福建南靖土楼导游词范本  南靖土楼是指遍布漳州市南靖、华安、平和、诏安、云霄、漳浦等县山区的土楼,以...
索溪峪导游词 索溪峪导游词10篇  作为一名可信赖的导游人员,总归要编写导游词,一篇完整的导游词,其结构一般包括习...
青海祁连山介绍导游词 青海祁连山介绍导游词  祁连山的平均山脉海拔在4000米~5000米之间,高山积雪形成的硕长而宽阔的...
威海幸福门导游词 威海幸福门导游词  作为一位兢兢业业的旅游从业人员,编写导游词是必不可少的,导游词不是以一代百、千篇...
浙江莫干山导游词 浙江莫干山导游词  浙江莫干山位于浙江省湖州市德清县境内,美丽富饶的沪、宁、杭金三角的中心。下面小编...
金界壕遗址导游词 金界壕遗址导游词  作为一名具备丰富知识的导游,就难以避免地要准备导游词,导游词的主要特点是口语化,...
世界遗产导游词 世界遗产导游词  各位游客,大家好!欢迎大家来到‘世界遗产’之称的古村落--...
贵州天河潭风景区的导游词 贵州天河潭风景区的导游词  各位游客们,我是你们导游×××,本次旅行的目的地是贵州的天河潭景区。天河...
河南开封山陕甘会馆导游词 河南开封山陕甘会馆导游词范文  各位朋友大家好,欢迎您来到山陕甘会馆,大家一路上辛苦了,我是您这次行...
介绍公园的导游词 介绍公园的导游词范文  篇一:北滘公园导游词  欢迎您前往北考公园。  北郊镇新中心城区,东承德路西...
小学生导游词结束语 导语:导游词是导游人员引导游客观光游览时的讲解词,是导游员同游客交流思想,向游客传播文化知识的工具,...
个园导游词   个园导游词(一)  个园是扬州现存历史最悠久、保存最完好的盐商园林,南临中国十大历史文化名街东关...
千岛湖景点导游词 千岛湖景点导游词  作为一位杰出的导游,就有可能用到导游词,一篇完整的导游词,其结构一般包括习惯用语...