移位操作符
位移操作符分为左移操作符和右移操作符,右移操作又分成两种为逻辑右移和算数右移,在使用时的操作数必须为整数,下面将会详细说明
左移操作符(<<)
使位数往左移动一个位数,移动完后左边抛弃,右边补0
int main()
{
int a = 10;
int b = a << 1;
printf("a = %d\n", a);
printf("b = %d\n", b);
return 0;
数字10的二进制为1010, 当往左移一个位数时变成了10100也就是20
右移操作符(<<)
右移操作符有两套规则,一个叫逻辑右移一个叫算数右移, 现在在市面上的集成开发环境都使用算数右移且目前没有使用逻辑开发的环境,下面来说他们有哪些不同
逻辑右移:右边抛弃,左边补零
算数右移:左边用原值的符号位填充,右边抛弃
int main()
{
int a = -10;
int b = a >> 1;
printf("a = %d\n", a);
printf("b = %d\n", b);
}
位操作符
位操作符分为四种,按位与(&)、按位或(|)、按位异或(^)按位取反(~),使用这四个符号的时候操作数必须为整数,使用方法为将十进制转成二进制在按位数进行运算
按位与(&)操作符
按位与特性为是只要其中一个有0就输出0要全部都是1才毁是1,拿10和8来做运算它们的二进制为1010(2)和1000(2)当进行了按位与的运算
经过按位与的运算后得到的答案为1000(2),也就是8
代码截图:
按位或(|)操作符
按位或特性为只要有1输出就为1,两个都是0才是0,这次拿1001(2)和0101(2)也就是9和5来运算
得到了1101(2),也就是13
代码截图
按位异或(^) 操作符
按位异或特性为相同为0相异为1,以1001(2)和0011(2)(分别为3和9)举例,将他们进行异或运算
得到的答案为1010(2),也就是10
代码截图:
按位取反(~)操作符
按位取反操作符的特性为只要输入输出相反,当我输入0进行取反输出为-1
实验代码:
int main() //按位与
{
int a = 10;
int b = 8;
int c = a & b;
printf("%d", c);
return 0;
}
int main() //按位或
{
int a = 9;
int b = 5;
int ans = 9 | 5;
printf("%d", ans);
return 0;
}
int main() //按位异或
{
int a = 9;
int b = 3;
int c = a ^ b;
printf("%d", c);
return 0;
}
int main() //按位取反
{
int a = 0;
int b = ~a;
printf("%d", b);
return 0;
}
练习1:求一个整数在内存中的二进制中1的个数
方法一:
int main()
{
int a = 0;
int count = 0;
scanf_s("%d",&a);
while (a)
{
if (a % 2 == 1) //只要检测到1
count++; //要打印的数+1
a = a / 2;
}
printf("%d", count);
return 0;
}
方法2:
int main()
{
int a = 0;
int count = 0;
scanf_s("%d",&a);
int b = 0;
for (b = 0; b < 32; b++)
{
if (a & (1 << b)) //当b每次往前移动一位和按位与的数字为1
count++; //count+1
}
printf("%d", count);
return 0;
}
方法3:
int main()
{
int a = 0;
int count = 0;
scanf_s("%d",&a);
int b = 0;
while (a)
{
a = a & (a - 1); //当a进行a和a-1的按位与a=1时
count++; //count+1
}
printf("%d", count);
return 0;
练习2:2进制位置0或者置1
编写代码将13⼆进制序列的第5位修改为1,然后再改回0
代码:
int main()
{
int a = 0;
scanf("%d", &a);
a = a | (1 << 4); 将数字1往前移动四位并做按位或运算
printf("%d\n", a);
a = a & (1 >> 4);将数字1往前移动四位取反并做按位与运算
printf("%d", a);
return 0;
}