❤️今天我们来学习位或
注意:本文中的位是从右往左来说的,也就是从低位开始数的!!!
一、昨日重现:
- 当然,在正式学习之前,让我们先看看昨天留下的问题:⭐️如何判断一个数是不是2的幂❓
✨要想解决这个问题,我们先要搞清楚,2的幂有什么特征?
2的幂 | 十进制表达 | 二进制表达 |
---|---|---|
2^0 | 1 | 0001 |
2^1 | 2 | 0010 |
2^2 | 4 | 0100 |
2^3 | 8 | 1000 |
… | … | … |
✨我们简单地列举出几个2的幂的二进制表达,可以发现,只有一位是1(且是首位),其余位全部是0。利用昨天学过的位与(&)知识,全1才1,有0则0,因此,将(2^n) & (2^n-1),结果必定是0,从而得到判断一个数是否是2的幂的方法之一:
if ( (n)&(n-1)==0 ) cout<<"n是2的幂";
二、基础知识:
✨C语言中的位或运算符|
是一种按位逻辑
运算符,用于对两个操作数
的每个位
执行逻辑或操作。位或操作的结果是两个操作数的每个对应位进行逻辑或
运算后的值。
位或运算符的使用方法如下:
result = operand1 | operand2;
- 其中,
operand1
和operand2
是要进行位或运算的两个操作数,result
是运算结果。
位或运算的规则如下:
-
(全0才0)
如果两个操作数的对应位都为0,则结果位为0。 -
(有1则1)
如果两个操作数的对应位有一个为1,则结果位为1。
(😄是不是和逻辑或很像呢❓)
示例如下:
#include <stdio.h>
int main() {
unsigned int a = 5; // 二进制表示为 0101
unsigned int b = 9; // 二进制表示为 1001
unsigned int result = a | b; // 二进制表示为 1101,十进制表示为 13
printf("result: %u\n", result);
return 0;
}
- 在上面的例子中,我们使用了两个无符号整数变量
a
和b
,它们的二进制表示分别为0101
和1001
。通过对这两个变量进行位或运算,我们得到了结果1101
,它的十进制表示为13。
三、拓展应用:
1. 设置特定位:
✨可以使用位或运算将某个变量的特定位设置为1,而不影响其他位的值。例如,可以使用位或运算设置标志位、控制位或权限位。
示例如下::
#include <stdio.h>
int main() {
unsigned int flags = 0; // 所有位都为0
unsigned int mask = 1; // 二进制表示为 0001
flags = flags | mask; // 将最低位设置为1
printf("flags: %u\n", flags);
return 0;
}
- 在上面的例子中,我们使用了一个无符号整数变量
flags
,它的所有位都为0。然后,我们定义了一个二进制表示为0001
的掩码mask
。通过对flags
和mask
进行位或运算,我们将flags
的最低位设置为1。最终,flags
的值变为1。
拓展思考:
❤️怎么将任意二进制的特定位置为1呢?置为0又该怎么做?
解:
-
✨我们首先来看第一个问题,将任意二进制的特定位置为1。
我这里有两种方法:
💗方法一:利用位或的思想
要将一个二进制数的第n位(从右往左,即从低位开始数)置为1,则只需要将该二进制数与2^(n-1)位或即可。比如对1001来说,要将第三位置为0,只需要将其与100(即4=2 ^(3-1))位或即可。
💗方法二:加法
先将该位置为0,再加上2^(n-1); -
✨对于第二个问题,将任意二进制的特定位置为0,解法与第一个问题类似。
💗方法一:利用位与的思想
将该数和111…101…111位与(这个二进制数只有特定位上是0,其余都是1)。比如要将1011第2位置为0,只需将其和1101位与即可。
💗方法二:减法
先将该位置为1,再减去2^(n-1);
❤️怎么将低位连续的0置为1呢?
解:对于11110000来说,要想将低位的4给零都置为1,只需要将其和11101111位或
即可。也就是n|(n-1)
.(这是一种特殊情况)
❤️怎么将低位的第一个零置为1呢?
解:对于11110111来说,要想将低位的第一个0置为1,只需要将其和11111000位或
即可。也即n|(n+1)
.(普遍情况)
2. 权限控制:
✨可以使用位或运算将不同的权限组合在一起。例如,可以使用不同的位代表不同的权限,然后通过位或运算将多个权限合并在一起。
#include <stdio.h>
#define READ_PERMISSION 1 // 二进制表示为 0001
#define WRITE_PERMISSION 2 // 二进制表示为 0010
#define EXECUTE_PERMISSION 4 // 二进制表示为 0100
int main() {
unsigned int permissions = 0;
permissions = permissions | READ_PERMISSION; // 设置读权限
permissions = permissions | WRITE_PERMISSION; // 设置写权限
printf("permissions: %u\n", permissions);
return 0;
}
- 在上面的例子中,我们使用了一个无符号整数变量
permissions
,它的所有位都为0。然后,我们定义了三个不同的权限标志,分别代表读权限、写权限和执行权限。通过对permissions和相应的权限标志进行位或运算,我们将读权限和写权限合并在一起。最终,permissions的值变为3。
3. 掩码操作:
✨可以使用位或运算来创建一个掩码,用于提取或设置特定的位。掩码是一个二进制数,其中每个位对应于要提取或设置的位。通过将掩码与另一个数进行位与或位或运算,可以提取或设置特定的位。(一般是位与)
#include <stdio.h>
#define BIT_MASK 0x0F // 二进制表示为 00001111
int main() {
unsigned int value = 0x3A; // 二进制表示为 00111010
unsigned int maskedValue = value & BIT_MASK;
printf("maskedValue: %u\n", maskedValue);
return 0;
}
- 在上面的例子中,我们使用了一个无符号整数变量value,它的二进制表示为00111010。然后,我们定义了一个掩码BIT_MASK,它的二进制表示为00001111。通过对value和掩码进行位与运算,我们提取了value的低4位。最终,maskedValue的值变为10。
4. 位标志:
✨可以使用位或运算来创建一个包含多个位标志的变量。每个位标志代表一个特定的状态或属性。通过位或运算将多个位标志合并在一起,可以在一个变量中同时表示多个状态或属性。(和权限控制有点类似)
#include <stdio.h>
#define FLAG_A 1 // 二进制表示为 0001
#define FLAG_B 2 // 二进制表示为 0010
#define FLAG_C 4 // 二进制表示为 0100
int main() {
unsigned int flags = 0;
flags = flags | FLAG_A; // 设置标志A
flags = flags | FLAG_B; // 设置标志B
printf("flags: %u\n", flags);
return 0;
}
- 在上面的例子中,我们使用了一个无符号整数变量flags,它的所有位都为0。然后,我们定义了三个不同的标志,分别代表标志A、标志B和标志C。通过对flags和相应的标志进行位或运算,我们将标志A和标志B合并在一起。最终,flags的值变为3。
5.位运算优化:
✨有时,使用位或运算可以优化代码的执行效率。例如,可以使用位或运算来替代一些复杂的逻辑运算,从而减少计算量和执行时间。
😄好了,今天的讲解就到这里了,相信你也是收获满满吧!文章来源:https://www.toymoban.com/news/detail-666610.html
附一张漂亮的流星雨照片:(许愿.gif)
文章来源地址https://www.toymoban.com/news/detail-666610.html
到了这里,关于第7天----【位运算进阶之----位或(|)】七夕特别版的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!