C语言的位运算符有~(取反)&(与运算) ^(异或运算) |(或运算) <<(左移) >> (右移),优先级 又高到低 排列为 ~ << >>(左移右移同级) & ^ | 。
其中左移和右移的左操作数只能是整型比如char int 之类的,其中char 和 short 会被提升为 int 型,右操作数的范围为(0~31),超出这个范围会出现不确定的结果。左移是二进制右边补0,右移是无符号二进制左边补零,有符号负数时左边补1,正数左边补0;
一个小问题 0x1 << 2+3 等于几?是5还是32呢?
printf("3 << 1 = %d\n",3<< 1 );//6
printf("3 << -1 = %d\n",3>> -1 );//不确定
printf("-1 << 1 = %d\n",-1 << 1 );//-2
printf("0x1 << 1 = %d\n",0x1<< 2+3 );//??
打印的是32说明+ - 运算符的优先级比<< >> 高。
int i = -1; int k = 1;
printf("k>>30 = %d\n", k >> 30);
printf("i >> 30 = %d\n", i >> 30);//有符号数右移是左边补位值不一样。
一个用二进制输出数的函数
int count_bit(unsigned a)
{
int bit = 0;
while (a)
{
if (a & 1)
{
bit++;
}
a >>= 1;
}
return bit;
}
int bits(void)
{
return count_bit(-1);
}
void printf_bit(char x)
{
int i;
for (i = bits()-1 ;i>=0;i--)
{
if ((i+1)%4 == 0)
{
printf(" ");
}
putchar(((x >> i) & 1) ? '1' : '0');
}
}
int main()
{
printf_bit(16);
system("pause");
return 0;
}
3种交换两个整数的方法
#define SWAP1(a, b) \
{ \
int t = a; \
a = b; \
b = t; \
}
#define SWAP2(a, b) \
{ \
a = a + b; \
b = a - b; \
a = a - b; \
}
#define SWAP3(a, b) \
{ \
a = a ^ b; \
b = a ^ b; \
a = a ^ b; \
}
2,不要混用数学运算符,位运算符,和逻辑运算符。
#include <stdio.h>
int main()
{
int i = 0;
int j = 0;
int k = 0;
if( ++i | ++j & ++k )
{
printf("Run here...\n");
}
return 0;
}
出现的结果不会是你所预期的结果。
防错准则
1:避免数学运算符,位运算符,和逻辑运算符出现在一个表达式中。
2:数学运算符,位运算符,和逻辑运算符出现在一个表达式中是用括号来表达计算次序。
左移和右移运算符的运算效率比数学运算符效率高
左移相当于x2;
右移相当于/2;
学习交流群199546072