1. 主页
  2. 文档
  3. C语言教程
  4. C语言运算符
  5. C/C++ 中的位运算符

C/C++ 中的位运算符

在 C 中,以下 6 个运算符是位运算符(在位级别工作) 

  1. C 或 C++ 中的&(按位与)将两个数字作为操作数,并对两个数字的每一位进行 AND。仅当两个位都为 1 时,AND 的结果才为 1。 
  2. C 或 C++ 中的(按位或)将两个数字作为操作数,并对两个数字的每一位进行 OR。如果两位中的任何一位为 1,则 OR 的结果为 1。 
  3. C 或 C++ 中的^(按位 XOR)将两个数字作为操作数,并对两个数字的每一位进行 XOR。如果两个位不同,则异或的结果为 1。 
  4. C 或 C++ 中的<<(左移)需要两个数字,左移第一个操作数的位,第二个操作数决定要移位的位数。 
  5. C 或 C++ 中的>>(右移)需要两个数字,右移第一个操作数的位,第二个操作数决定要移位的位数。 
  6. C 或 C++ 中的~(按位非)取一个数字并将其所有位取反 

例子:

#include <iostream>
using namespace std;

int main() {
// a = 5(00000101), b = 9(00001001)
int a = 5, b = 9;

// The result is 00000001
cout<<"a = " << a <<","<< " b = " << b <<endl;
cout << "a & b = " << (a & b) << endl;

// The result is 00001101
cout << "a | b = " << (a | b) << endl;

// The result is 00001100
cout << "a ^ b = " << (a ^ b) << endl;

// The result is 11111010
cout << "~(" << a << ") = " << (~a) << endl;

// The result is 00010010
cout<<"b << 1" <<" = "<< (b << 1) <<endl;

// The result is 00000100
cout<<"b >> 1 "<<"= " << (b >> 1 )<<endl;

return 0;
}

// This code is contributed by sathiyamoorthics19
// C Program to demonstrate use of bitwise operators
#include <stdio.h>
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. 左移和右移运算符不应用于负数。如果第二个操作数(决定移位次数)是负数,则会导致 C 中的未定义行为。例如 1 <<- 1 和 1 >> -1 的结果都是未定义的。此外,如果数字的移位大于整数的大小,则行为未定义。例如,如果整数使用 32 位存储,则 1 << 33 是​​未定义的。另一件事是,如果additive-expression(决定没有移位的操作数)为0,则不执行移位操作。有关更多详细信息,请参见this。 
    注意:C++ 中,这种行为是明确定义的。
  2. 按位异或运算符是最有用的运营商一个技术面试的观点。它用于许多问题。一个简单的例子可以是“给定一组数字,其中除了一个数字之外所有元素都出现偶数次,找到奇数出现的数字”这个问题可以通过对所有数字进行异或来有效地解决。 
#include <iostream>
using namespace std;

// 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]);
cout << "The odd occurring element is "<< findOdd(arr, n);
return 0;
}
#include <stdio.h>

// 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

不应使用位运算符代替逻辑运算符。逻辑运算符(&&、|| 和 !)的结果是 0 或 1,但按位运算符返回一个整数值。此外,逻辑运算符将任何非零操作数视为 1。例如,考虑以下程序,对于相同的操作数,& 和 && 的结果是不同的。 

#include <iostream>
using namespace std;

int main()
{
int x = 2, y = 5;
(x & y) ? cout <<"True " : cout <<"False ";
(x && y) ? cout <<"True " : cout <<"False ";
return 0;
}
#include <stdio.h>

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 <iostream>
using namespace std;

int main() {

int x = 19;
cout<<"x << 1 = "<< (x << 1) <<endl;
cout<<"x >> 1 = "<< (x >> 1) <<endl;
return 0;
}
#include <stdio.h>

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 <iostream>
using namespace std;

int main() {

int x = 19 ;
(x & 1) ? cout<<"Odd" : cout<< "Even" ;

return 0;
}
#include <stdio.h>

int main()
{
int x = 19;
(x & 1) ? printf("Odd") : printf("Even");
return 0;
}

输出: 

Odd
  • ~ 操作符要小心使用。如果结果存储在无符号变量中,则 ~ 运算符对小数的结果可能是大数。如果结果存储在有符号变量中,则结果可能是负数(假设负数以 2 的补码形式存储,其中最左边的位是符号位) 
#include <iostream>
using namespace std;

int main() {

unsigned int x = 1;
signed int a = 1;
cout<<"Signed Result "<< ~a <<endl ;
cout<<"Unsigned Result "<< ~x ;
return 0;
}
// Note that the output of the following
// program is compiler dependent
#include <stdio.h>

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

 

这篇文章对您有用吗?