移位操作符
右移
右移移位分为:
算术移位:右边丢弃,左边补原符号位
逻辑移位:右边丢弃,左边补0
正数移位方法
一个二进制数包含原码 反码 补码
当移位的时候,移动的是补码
正数
例如:
int a=16;
原码,反码,补码均为
00000000000000000000000000010000
如果将a右移一位
int b = a>>1;
补码的右边丢弃,左边添加符号位。
补码变成:00000000000000000000000000001000
又因为正数的原反补一样,所以转换为十进制。
a变为了8。
负数移位方法
例如:
int a=-1;
int b=a>>1;
第一位为符号位 a的二进制原码为
10000000000000000000000000000001
反码:符号位不变 其他按位取反
111111111111111111111111111111111110
补码:反码+1
111111111111111111111111111111111111
右移之后
丢了右边的1,左边补了个1,没有变化
所以 右移之后 b还是-1。
左移
只有一种方式
左边丢弃,右边补0
位操作符
位操作符有:
& 按位与;
| 按位或;
^ 按位异或;
按位与
int c = a&b;
比较补码,如果a的补码二进制与b的补码二进制相同位全部为1,则c的二进制位为1;
例如 补码a:00000000000000000000000000000101
补码b:00000000000000000000000000000100
补码c:00000000000000000000000000000100
按位或
int c = a|b;
比较补码,如果a的补码二进制与b的补码二进制相同位有一个为1,则c的二进制位为1;
例如 补码a:00000000000000000000000000000111
补码b:00000000000000000000000000000100
补码c:00000000000000000000000000000111
按位异或
int c = a^b;
比较补码,在c的补码中,如果a的补码二进制与b的补码二进制相同位为0,不同位为1;
例如 补码a:00000000000000000000000000000111
补码b:00000000000000000000000000000100
补码c:00000000000000000000000000000011
实用面试题
在不建立临时变量的基础上,将整数a与整数b的值交换
写法1:简单写法
int main()
{
int a = 3;
int b = 5;
a = a + b;
b = a - b;
a = a - b;
printf("a = %d\nb = %d ", a, b);
return 0;
}
写法2:异或写法
将 a ^ b 的值当作密码。
int main()
{
int a = 3;
int b = 5;
a = a ^ b;
b = a ^ b;
a = a ^ b;
printf("a = %d\nb = %d ", a, b);
return 0;
}
会考,但不实用。
练习:求一个整数存储在内存中的二进制数中1的个数
第一种写法:负数不可用
#include<stdio.h>
int main()
{
int a = 0;
scanf("%d", &a);
int count = 0;
while (a)
{
if (a % 2 == 1)
count++;
a = a / 2;
}
printf("%d", count);
return 0;
}
赋值操作符
复合赋值符
int a = 0;
a+=1 == a=a+1;
a&=1
a*=2
a*=2
a%=2
类似这种
单目操作符
只有一个操作数
!操作符
真变假,假变真
int a = 0;
a=!a;
a==1;
int a = 10;
a=!a;
a==0;
运用场景
int a = 0;
if(!a)//如果a为假,打印hehe
{
printf("hehe\n");
}
取地址操作符 &
int a = 10;
int* p = &a;//用指针存储a的地址
*P ; //解引用操作,得到的就是a的值
操作数的类型长度 sizeof
int main()
{
char c = '0';
int arr[10] = { 0 };
int a = 0;
char* p = &c;
printf("%d", sizeof(a));//4
printf("%d", sizeof(int));
printf("%d", sizeof(c));//1
printf("%d", sizeof(char));
printf("%d", sizeof(p));//4
printf("%d", sizeof(char*));
printf("%d", sizeof(arr));//40
printf("%d", sizeof(int[10]));
//对于数组来说 去掉名字剩下的就是类型
}
对于数组来说,去掉名字剩下的就是类型
经典题
int main()
{
short s = 0;
int a = 0;
printf("%d\n", sizeof(s = a + 5));
printf("%d\n", s);
}
客随主便,sizeof里面是短整型
s的值并未改变。
所以是打印出来是 2 和 0