逍遥自在学C语言 | 位运算符的基础用法
Posted 知微之见
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了逍遥自在学C语言 | 位运算符的基础用法相关的知识,希望对你有一定的参考价值。
前言
一、人物简介
- 第一位闪亮登场,有请今后会一直教我们C语言的老师 —— 自在。
- 第二位上场的是和我们一起学习的小白程序猿 —— 逍遥。
二、构成和表达方式
- 位运算符是一组用于在二进制数之间进行操作的运算符
运算符 | 名称 | 示例 |
---|---|---|
& | 位与 | a && b |
| | 位或 | a | b |
^ | 位异或 | a ^ b |
~ | 位取反 | ~a |
<< | 二进制左移 | a << 2 |
>> | 二进制右移 | a >> 2 |
三、位运算符的应用
1、位与运算符 (&)
-
位与运算符用符号
&
表示。 -
如果两个操作数的对应位都为1,则位与运算的结果为1,否则结果为0
-
示例代码
#include <stdio.h>
int main()
int a = 13; //二进制表示为0b1101
int b = 11; //二进制表示为0b1011
int c = a & b;
printf("%d\\n", c); //输出结果为9,二进制表示为0b1001
return 0;
2、位或运算符 (|)
-
位或运算符用符号
|
表示。 -
如果两个操作数的对应位中至少有一个为1,则位或运算的结果为1,否则结果为0。
-
示例代码
#include <stdio.h>
int main()
int a = 13; //二进制表示为0b1101
int b = 11; //二进制表示为0b1011
int c = a | b;
printf("%d\\n", c); //输出结果为15,二进制表示为0b1111
return 0;
3、位异或运算符 (^)
-
位异或运算符用符号
^
表示 -
如果两个操作数的对应位不同,则位异或运算的结果为1,否则结果为0
-
示例代码
#include <stdio.h>
int main()
int a = 13; //二进制表示为0b1101
int b = 11; //二进制表示为0b1011
int c = a ^ b;
printf("%d\\n", c); //输出结果为6,二进制表示为0b0110
return 0;
4、位取反运算符 (~)
-
位取反运算符用符号
~
表示 -
它会对操作数的每个二进制位取反,即0变成1,1变成0
-
示例代码
#include <stdio.h>
int main()
int a = 13; //二进制表示为0b1101
int b = ~a;
printf("%d\\n", b); //输出结果为-14,二进制表示为0b11111111111111111111111111110010
return 0;
5、左移运算符 (<<)
-
左移运算符用符号
<<
表示 -
它将操作数的所有二进制位向左移动指定的位数,并在低位填充0
-
示例代码
#include <stdio.h>
int main()
int a = 13; //二进制表示为0b1101
int b = a << 2;
printf("%d\\n", b); //输出结果为52,二进制表示为0b110100
return 0;
6、右移运算符 (>>)
-
右移运算符用符号
>>
表示。 -
它将操作数的所有二进制位向右移动指定的位数,并在高位填充0或1(具体取决于操作数的符号)
-
示例代码
#include <stdio.h>
int main()
int a = 13; //二进制表示为0b1101
int b = a >> 2;
printf("%d\\n", b); //输出结果为3,二进制表示为0b0011
return 0;
小结
通过本文的讲解,我们学会了6种位运算符的基础用法,在接下来的文章中,将会继续介绍这6种位运算符的高级用法。
📢欢迎各位 👍点赞 ⭐收藏 📝评论,如有错误请留言指正,非常感谢!
光天化日学C语言(15)- 位运算 | 的应用
📢博客主页:https://blog.csdn.net/WhereIsHeroFrom
📢欢迎各位 👍点赞 ⭐收藏 📝评论,如有错误请留言指正,非常感谢!
📢本文由 英雄哪里出来 原创,转载请注明出处,首发于 🙉 CSDN 🙉
作者的专栏:
👉C语言基础专栏《光天化日学C语言》
👉C语言基础配套试题详解《C语言入门100例》
👉算法进阶专栏《夜深人静写算法》
一、前言
本文作者是从 2007 年开始学 C语言 的,不久又接触了C++,基本就是 C/C++ 技术栈写了 14 年的样子,不算精通,但也算差强人意。著有《夜深人静写算法》系列,且承诺会持续更新,直到所有算法都学完。主要专攻 高中 OI 、大学 ACM、 职场 LeetCode 的全领域算法。由于文章中采用 C/C++ 的语法,于是就有不少读者朋友反馈语言层面就被劝退了,更何况是算法。
于是,2021 年 06 月 12 日,《光天化日学C语言》 应运而生。这个系列文章主要服务于高中生、大学生以及职场上想入坑C语言的志同道合之人,希望能给祖国引入更多编程方面的人才,并且让自己的青春不留遗憾!
这一章的主要内容是位或运算符的应用。
二、人物简介
- 第一位登场的就是今后会一直教我们C语言的老师 —— 光天。
- 第二位登场的则是今后会和大家一起学习C语言的没什么资质的小白程序猿 —— 化日。
三、位或运算符
- 位或运算符是一个二元的位运算符,也就是有两个操作数,表示为
x | y
。 - 位或运算会对操作数的每一位按照如下表格进行运算,对于每一位只有 0 或 1 两种情况,所以组合出来总共 2 2 = 4 2^2 = 4 22=4 种情况。
左操作数 | 右操作数 | 结果 |
---|---|---|
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 1 |
- 通过这个表,我们得出一些结论:
- 1)无论是 0 或 1,只要位或上 1,就变成1;
- 2)只有当两个操作数都是0的时候,才变成 0;
#include <stdio.h>
int main() {
int a = 0b1010; // (1)
int b = 0b0110; // (2)
printf("%d\\n", (a | b) ); // (3)
return 0;
}
-
(
1
)
(1)
(1) 在C语言中,以
0b
作为前缀,表示这是一个二进制数。那么a
的实际值就是 ( 1010 ) 2 (1010)_2 (1010)2。 -
(
2
)
(2)
(2) 同样的,
b
的实际值就是 ( 0110 ) 2 (0110)_2 (0110)2; -
(
3
)
(3)
(3) 那么这里
a | b
就是对 ( 1010 ) 2 (1010)_2 (1010)2 和 ( 0110 ) 2 (0110)_2 (0110)2 的每一位做表格中的|
运算。 - 所以最后输出结果为:
14
- 因为输出的是十进制数,它的二进制表示为: ( 1110 ) 2 (1110)_2 (1110)2。
四、位或运算符的应用
1、设置标记位
【例题1】给定一个数,判断它二进制低位的第 5 位,如果为 0,则将它置为 1。
- 这个问题,我们很容易联想到位或。
- 我们分析一下题目意思,如果第 5 位为 1,不用进行任何操作;如果第 5 位为 0,则置为 1。言下之意,无论第五位是什么,我们都直接置为 1即可,代码如下:
#include <stdio.h>
int main() {
int x;
scanf("%d", &x);
printf("%d\\n", x | 0b10000);
return 0;
}
2、置空标记位
【例题2】给定一个数,判断它二进制低位的第 5 位,如果为 1,则将它置为 0。
- 这个问题,我们在学过 光天化日学C语言(14)- 位运算 & 的应用 以后,很容易得出这样一种做法:
#include <stdio.h>
int main() {
int x;
scanf("%d", &x);
printf("%d\\n", x & 0b11111111111111111111111111101111);
return 0;
}
- 其它位不能变,所以位与上1;第5位要置零,所以位与上0;
- 这样写有个问题,就是这串数字太长了,一点都不美观,而且容易写错,当然我们也可以转换成 十六进制,转换的过程也有可能出错。
- 而我们利用位或,只能将第5位设置成1,怎么把它设置成0呢?
我们可以配合减法来用。分成以下两步:
1)首先,强行将低位的第5位置成1;
2)然后,强行将低位的第5位去掉;
- 第 ( 1 ) (1) (1) 步可以采用位或运算,而第 ( 2 ) (2) (2) 步,我们可以直接用减法即可。
- 代码实现如下:
#include <stdio.h>
int main() {
int x;
int a = 0b10000;
scanf("%d", &x);
printf("%d\\n", (x | a) - a );
return 0;
}
- 注意:直接减是不行的,因为我们首先要保证那一位为 1,否则贸然减会产生借位,和题意不符。
3、低位连续零变一
【例题3】给定一个整数 x x x,将它低位连续的 0 都变成 1。
- 假设这个整数低位连续有 k k k 个零,二进制表示如下:
- . . . 1 00...00 ⏟ k ...1\\underbrace{00...00}_{\\rm k} ...1k 00...00
- 那么,如果我们对它进行减一操作,得到的二进制数就是:
- . . . 0 11...11 ⏟ k ...0\\underbrace{11...11}_{\\rm k} ...0k 11...11
- 我们发现,只要对这两个数进行位或,就能得到:
- . . . 1 11...11 ⏟ k ...1\\underbrace{11...11}_{\\rm k} ...1k 11...11
- 也正是题目所求,所以代码实现如下:
#include <stdio.h>
int main() {
int x;
scanf("%d", &x);
printf("%d\\n", x | (x-1) ); // (1)
return 0;
}
-
(
1
)
(1)
(1)
x | (x-1)
就是题目所求的 “低位连续零变一” 。
4、低位首零变一
【例题4】给定一个整数 x x x,将它低位第一个 0 变成 1。
- 记得在评论区留下你的答案哦 ~
通过这一章,我们学会了:
1)用位运算 | 来做标记位的设置;
2)用位运算 | 来做标记位的清除;
3)用位运算 | 将低位连续的零变成一;
- 希望对你有帮助哦 ~ 祝大家早日成为 C 语言大神!
课后习题
📢博客主页:https://blog.csdn.net/WhereIsHeroFrom
📢欢迎各位 👍点赞 ⭐收藏 📝评论,如有错误请留言指正,非常感谢!
📢本文由 英雄哪里出来 原创,转载请注明出处,首发于 🙉 CSDN 🙉
作者的专栏:
👉C语言基础专栏《光天化日学C语言》
👉C语言基础配套试题详解《C语言入门100例》
👉算法进阶专栏《夜深人静写算法》
以上是关于逍遥自在学C语言 | 位运算符的基础用法的主要内容,如果未能解决你的问题,请参考以下文章
光天化日学C语言(19)- 位运算 >> 的应用 | 右移的一些高端用法