位运算:与(&)、或(|)、非(~)
位运算:与(&)、或(|)、非(~)
掌握位运算:与(&)、或(|)、非(~)的基本使用方法及原理。
位运算在每一个二进制位上独立计算,不要和逻辑运算 &&、||、! 混用。与 &:两位都为 1 才得 1,常用来「取出某几位」(与掩码相与)。或 |:有一位为 1 就得 1,常用来「置 1 某几位」。非 ~:按位取反;在 int 上按机器字长(通常 32 位)翻转,结果常是负数,按补码解读。~x 等于 -x-1。
三级客观题会给两个小整数,要求口算 &、|、~ 的十进制结果,或判断「& 能否当逻辑与用」。判断题爱设陷阱:5 & 0 与 5 && 0 不同。编程里可用 & 1 取最低位、| (1 << k) 把第 k 位置 1。认证标准以 C++11 为准,且不考未定义行为,移位与取反都按有符号 int 的补码来理解即可。
int a = 5, b = 3; // 0101 与 0011
cout << (a & b); // 1 (0001)
cout << (a | b); // 7 (0111)
cout << (~a); // -6(~5 == -6)
先写成同样宽度的二进制再对位;把 ~ 当成逻辑非、或只反最低几位,都会算错。
如果 a 为 int 类型的变量,下列哪个表达式可以正确求出满足“小于等于 a 且是 4 的倍数”的整数中最大的?( )
原文保真说明:来源改写 1 处(照原卷保留,未作修改)
来源题面被改写多余符号题干
原卷作
( )洛谷有题漏了题干末尾答题空( );官方 PDF 第 4 页有。已按页面图像恢复。
已按官方原件恢复:现为原卷原文
在下列代码的横线处填写( ),可以使得输出不是 “31”。
#include <iostream>
using namespace std;
int main() {
int array[5] = {1, 2, 4, 8, 16};
int res = 0;
for (int i = 0; i < 5; i++)
________; // 在此处填写代码
cout << res << endl;
return 0;
}
如果 a 为 int 类型的变量,且表达式 ((a | 3) == 3) 的值为 true,则说明 a 在从 0 到 3 之间(可能为 0、可能为 3)。
以下哪个不是 C++ 语言中的运算符?( )
在 C++ 语言中,位运算符也有类似“先乘除、后加减”的优先级规则。因此,使用时应注意合理使用括号。
如果 a 为 int 类型的变量,且表达式 ((a & 1) == 0) 的值为 true,则说明 a 是偶数。
下面 C++ 代码执行后的输出是( )。
int main()
{
cout << (3|16) << endl;
cout << endl;
return 0;
}
定义整型变量 int a=3, b=16,则 a|b 的值和 a+b 的关系是( )。
如果 a 为 int 类型的变量,且表达式 ((a | 3) == 3) 的值为 true,则说明 a 在从 0 到 3 之间(可能为 0、可能为 3)。
下面说法正确的是( )
a & ~1 运算实现的是( )。
下列程序中,result 和 result2 输出分别是( )
long a = 123;
int b = 1;
long result = a & b;
cout<<result<<endl;
long a2 = -123;
unsigned int b2 = -1;
long result2 = a2 & b2;
cout<<result2<<endl;
原文保真说明:来源改写 1 处(照原卷保留,未作修改)
来源题面被改写版式题干
原卷作
cout<<result<<endl;洛谷有题 cout 两侧加了空格;已按官方 PDF 第 3 页列位恢复为 cout<<result<<endl / cout<<result2<<endl。
已按官方原件恢复:现为原卷原文
~1 的输出值是 −2。( )
~1 = 1111 1110。( )
取 X 的低四位,可以用 Y = 0000 1111,用 X & Y 获取 X 的低四位。( )
下面逻辑运算中,正确的是( )。
a | 10(a 与 10 都是 10 进制,且二进制表示最高位为 1)运算的结果是( )。
下列程序输出的是 A
char x=65;
x=x&00001111;
cout<<x<<endl;
这段程序进行的是判断一个从键盘输入的字符的 ASCII 是否是奇数,若是,输出 YES,否则,输出 NO
int main()
{
char x;
scanf("%c", &x);
int ASCII = (int)x;
cout << (x & 1 ? "YES" : "NO") << '\n';
return 0;
}
2025
C++时间 1 s内存 512 MB标准输入输出
小 A 有一个整数 x,他想找到最小的正整数 y 使得下式成立:
(x and y)+(x or y)=2025其中 and 表示二进制按位与运算,or 表示二进制按位或运算。如果不存在满足条件的 y,则输出 −1。
输入格式
一行,一个整数 x。
输出格式
一行,一个整数,若满足条件的 y 存在则输出 y,否则输出 −1。
样例
1025
1000
数据范围
对于所有测试点,保证 0≤x<2025。
(x and y)+(x or y)=2025其中:
- and 表示按位与运算,运算符为 &。
- or 表示按位或运算,运算符为 ∣。
你的代码(C++)
提交后由评测机编译运行,结果见下方76 B / 64 KB
判题结果
二进制数 1010∣1100 的结果是( )
(x & 1) == 0 可以判断整数 x 是否为偶数。
奇偶校验
C++时间 1 s内存 512 MB标准输入输出
数据在传输过程中可能出错,因此接收方收到数据后通常会校验传输的数据是否正确,奇偶校验是经典的校验方式之一。
给定 n 个非负整数 c1,c2,…,cn 代表所传输的数据,它们的校验码取决于这些整数在二进制下 1 的数量之和的奇偶性。如果这些整数在二进制下共有奇数个 1,那么校验码为 1;否则校验码为 0。你能求出这些整数的校验码吗?
输入格式
第一行,一个正整数 n,表示所传输的数据量。
第二行,n 个非负整数 c1,c2,…,cn,表示所传输的数据。
输出格式
输出一行,两个整数,以一个空格分隔:
第一个整数表示 c1,c2,…,cn 在二进制下 1 的总数量;
第二个整数表示校验码(0 或 1)。
样例
4 71 69 83 80
13 1
6 1 2 4 8 16 32
6 0
数据范围
对于所有测试点,保证 1≤n≤100,0≤ci≤255。
你的代码(C++)
提交后由评测机编译运行,结果见下方76 B / 64 KB
判题结果
已知字符串 s = "C++ Programming",下列程序运行的结果是( )
cout << (int)(s.length() | 3) << endl;
以下代码运行后,sum 的结果是( )
int arr[5] = {2, 4, 6, 8, 10};
int sum = 0;
for (int i = 0; i < 5; i++) {
switch (arr[i] % (1|2)) {
case 0: sum += 1; break;
case 1: sum += 2; break;
case 2: sum += 3; break;
}
}
位运算符 &、|、^、~ 的优先级高于算术运算符 +、-、*、/。
补码的情况下,关于按位取反运算,用笔计算的情况下,以下说法错误的是:( )
在 C++ 位运算中,各种不同的运算符有优先级的区分,使用括号能够解决优先级的问题。
如果 a 为 int 类型的变量,且 a 的二进制最低位为 0 ,则表达式 ((a & 3 & 1) == 0) 的值为 true 。
在 C++ 中,对于 32 位有符号整数 int 类型数据 n,关于按位取反运算符 ~,下列说法正确的是( )。
下面选项中提到的变量都是正整数,关于位运算,下面说法错误的是( )。
a=7, b=3, c=14, d=15, e=8,对于运算表达式 !a << b & c ^ d | e 的结果是( )。
如果 a 为 int 类型的变量,且表达式 ((a & 1) == 1) 的值为 true,则说明 a 是奇数。