在C中,以下6个运算符是按位运算运算符(在位级别工作)
- C或C++中的&(按位与)将两个数字作为操作数,并对两个数字的每一位进行“与”运算。仅当两个位均为1时,AND的结果才为1。
- 的|在C或C++中(按位或)将两个数字作为操作数,并对两个数字的每一位进行“或”运算。如果两个位中的任何一个为1,则OR的结果为1。
- C或C++中的^(按位XOR)将两个数字用作操作数,并对两个数字的每一位进行XOR。如果两个位不同,则XOR的结果为1。
- 在C或C++中, <<(左移)采用两个数字,左移第一个操作数的位,第二个操作数确定要移位的位数。
- C或C++中的>>(右移)采用两个数字,右移第一个操作数的位,第二个操作数确定要移位的位数。
- C或C++中的〜(按位NOT)取一个数字并将其所有位求反
例子:
// C Program to demonstrate use of bitwise operators
#include
int main()
{
// a = 5(00000101), b = 9(00001001)
unsigned char a = 5, b = 9;
// The result is 00000001
printf("a = %d, b = %d\n", a, b);
printf("a&b = %d\n", a & b);
// The result is 00001101
printf("a|b = %d\n", a | b);
// The result is 00001100
printf("a^b = %d\n", a ^ b);
// The result is 11111010
printf("~a = %d\n", a = ~a);
// The result is 00010010
printf("b<<1 = %d\n", b << 1);
// The result is 00000100
printf("b>>1 = %d\n", b >> 1);
return 0;
}
输出:
a = 5, b = 9
a&b = 1
a|b = 13
a^b = 12
~a = 250
b<<1 = 18
b>>1 = 4
关于按位运算运算符的有趣事实
- 左移位运算符和右移位运算符不应用于负数。如果任何一个操作数为负数,则将导致未定义的行为。例如,-1 << 1和1 << -1的结果均未定义。另外,如果数字移位的幅度大于整数的大小,则该行为是不确定的。例如,如果使用32位存储整数,则1 << 33是未定义的。有关更多详细信息,请参见此内容。
- 从技术面试的角度来看,按位XOR运算符是最有用的运算符。它用于许多问题。一个简单的例子是“给出一组数字,其中所有元素除一个数字外均出现偶数次,找到奇数出现的数字”。只需对所有数字进行异或运算,就可以有效地解决此问题。
#include
// Function to return the only odd // occurring element int findOdd(int arr[], int n) { int res = 0, i; for (i = 0; i < n; i++) res ^= arr[i]; return res; } // Driver Method int main(void) { int arr[] = { 12, 12, 14, 90, 14, 14, 14 }; int n = sizeof(arr) / sizeof(arr[0]); printf("The odd occurring element is %d ", findOdd(arr, n)); return 0; } 输出:The odd occurring element is 90
以下是使用XOR运算符的许多其他有趣的问题。
- 查找丢失的号码
- 在不使用临时变量的情况下交换两个数字
- 内存有效的双链表
- 找到两个不重复的元素。
- 在未排序的数组中找到出现奇数的两个数字。
- 在不使用算术运算运算符的情况下将两个数字相加。
- 将位交换为给定的数字/。
- 计算要翻转以将a转换为b的位数。
- 找到一次出现的元素。
- 检测两个整数是否具有相反的符号。
。
- 不应使用按位运算运算符代替逻辑运算符。逻辑运算符(&&,||和!)的结果为0或1,但按位运算运算符返回整数值。另外,逻辑运算符会将任何非零操作数都视为1。例如,考虑以下程序,对于相同的操作数,&和&&的结果是不同的。
#include
int main() { int x = 2, y = 5; (x & y) ? printf("True ") : printf("False "); (x && y) ? printf("True ") : printf("False "); return 0; } 输出:False True
- 左移和右移运算符分别等效于2的乘法和除法。如第1点所述,它仅在数字为正数时起作用。
#include
int main() { int x = 19; printf("x << 1 = %d\n", x << 1); printf("x >> 1 = %d\n", x >> 1); return 0; } 输出:x << 1 = 38 x >> 1 = 9
- &运算符可用于快速检查数字是否为奇数或偶数。仅当x为奇数时,表达式(x&1)的值才为非零,否则值为零。
#include
int main() { int x = 19; (x & 1) ? printf("Odd") : printf("Even"); return 0; } 输出:Odd
- 〜运算符应小心使用。如果结果的〜运算符存储在一个无符号变量中,那么它的结果可能是一个很大的数字。如果结果存储在有符号变量中,则结果可能是负数(假设负数以2的补码形式存储,其中最左边的位是符号位)
// Note that the output of the following // program is compiler dependent #include
int main() { unsigned int x = 1; printf("Signed Result %d \n", ~x); printf("Unsigned Result %ud \n", ~x); return 0; } 输出:Signed Result -2 Unsigned Result 4294967294d
重要链接:
- 位操作(重要策略)
- 竞争编程的按位技巧
- 竞争编程的位技巧
要从最佳影片策划和实践问题去学习,检查了C++基础课程为基础,以先进的C++和C++ STL课程基础加上STL。要完成从学习语言到DS Algo等的更多准备工作,请参阅“完整面试准备课程” 。