1. 操作符分类:
算术操作符
移位操作符
位操作符
赋值操作符
单目操作符
关系操作符
逻辑操作符
条件操作符
逗号表达式
下标引用、函数调用和结构成员
2. 算术操作符
+ - * / %
3. 移位操作符
<< 左移操作符
>> 右移操作符
注:移位操作符的操作数只能是整数。
左移操作符
移位规则:
左边丢弃,右边补0
注:移位操作符的操作数只能是整数。
//符号位:
//0 - 正数
//1 - 负数
//二进制有三种表达方式
//原码
//反码(原码的符号不变,其他位置按位取反得到的就是反码)
//补码(反码+1就是补码)
int main()
{
//正整数的原码、反码、补码是相同的
int a = 5;//5
int b = a << 1;//10
//a(5)的原码、反码、补码
//原码: 00000000 00000000 00000000 00000101
//反码: 00000000 00000000 00000000 00000101
//补码: 00000000 00000000 00000000 00000101
//b(10)的原码、反码、补码
//原码: 00000000 00000000 00000000 00001010
//反码: 00000000 00000000 00000000 00001010
//补码: 00000000 00000000 00000000 00001010
//负数的原码、反码、补码是要计算的
int c = -5;//-5
int d = c << 1;//-10
//c(-5)的原码、反码、补码
//原码: 10000000 00000000 00000000 00000101
//反码: 11111111 11111111 11111111 11111010
//补码: 11111111 11111111 11111111 11111011
//如何得出d呢?
//将a的补码左边丢弃,右边补0,得到
// 11111111 11111111 11111111 11110110
//
//
//d(-10)的原码、反码、补码
//补码: 11111111 11111111 11111111 11110110
//反码: 11111111 11111111 11111111 11110101
//原码: 10000000 00000000 00000000 00001010
printf("%d\n", a);
printf("%d\n", b);
printf("%d\n", c);
printf("%d\n", d);
return 0;
}
右移操作符
移位规则:
- 逻辑右移:右边丢弃,左边补0
- 算数右移:右边丢弃,左边补原符号位
int main()
{
int a = 5;
int b = a >> 1;
//a(5)的原码、反码、补码
//原码: 00000000 00000000 00000000 00000101
//反码: 00000000 00000000 00000000 00000101
//补码: 00000000 00000000 00000000 00000101
//如何得出d呢?
//将a的补码右边丢弃,左边补0,得到
// 00000000 00000000 00000000 00000010
int c = -5;//-5
int d = c >> 1;//-3
//c(-5)的原码、反码、补码
//原码: 10000000 00000000 00000000 00000101
//反码: 11111111 11111111 11111111 11111010
//补码: 11111111 11111111 11111111 11111011
//在vs中采用算数右移,这个取决于编译器
//d(-3)的原码、反码、补码
//补码: 11111111 11111111 11111111 11111101
//反码: 11111111 11111111 11111111 11111100
//原码: 10000000 00000000 00000000 00000011
printf("%d\n", a);
printf("%d\n", b);
printf("%d\n", c);
printf("%d\n", d);
return 0;
}
警告⚠ : 对于移位运算符,不要移动负数位,这个是标准未定义的。 例如:
int num = 10;
num >> -1;//error
4. 位操作符
位操作符有:
& //按(二进制)位与
| //按(二进制)位或
^ //按(二进制)位异或
注:他们的操作数必须是整数
& ------------ 按位与
& --> 01/10 --> 0
00 --> 0 11 --> 1
int main()
{
int a = 3;
int b = -5;
int c = a & b;
//a的补码 00000000 00000000 00000000 00000011
//b的原码 10000000 00000000 00000000 00000101
// 反码 11111111 11111111 11111111 11111010
// 补码 11111111 11111111 11111111 11111011
// 00000000 00000000 00000000 00000011
//& --> 01/10 --> 0
// 00 --> 0 11 --> 1
//a & b
//00000000 00000000 00000000 00000011(补码) --> 3
//正数原反补码相同
printf("c的结果是:%d\n", c);
return 0;
}
| --------------- 按位或
| --> 01/10 --> 1
00 --> 0 11 --> 1
int main()
{
int a = 3;
int b = -5;
int c = a | b;
//a的补码 00000000 00000000 00000000 00000011
//b的原码 10000000 00000000 00000000 00000101
// 反码 11111111 11111111 11111111 11111010
// 补码 11111111 11111111 11111111 11111011
// 00000000 00000000 00000000 00000011
//| --> 01/10 --> 1
// 00 --> 0 11 --> 1
// 11111111 11111111 11111111 11111011(补码)
// 11111111 11111111 11111111 11111010(反码)
//a | b --> 10000000 00000000 00000000 00000101(原码) --> -5
printf("c的结果是:%d\n", c);
return 0;
}
^ ----------------- 按位异或
^ --> 00/11 --> 0
01/10 --> 1
int main()
{
int a = 3;
int b = -5;
int c = a ^ b;
//a的补码 00000000 00000000 00000000 00000011
//b的原码 10000000 00000000 00000000 00000101
// 反码 11111111 11111111 11111111 11111010
// 补码 11111111 11111111 11111111 11111011
// 00000000 00000000 00000000 00000011
// ^ --> 00/11 --> 0
// 01/10 --> 1
// 11111111 11111111 11111111 11111000(补码)
// 11111111 11111111 11111111 11110111(反码)
//a ^ b --> 10000000 00000000 00000000 00001000(原码) --> -8
//
printf("%d\n", c);
return 0;
}
a ^ a = 0
0 ^ a = a
不能创建临时变量(第三个变量),实现两个数的交换
#include <stdio.h>
int main()
{
int a = 10;
int b = 20;
a = a^b;
b = a^b;
a = a^b;
printf("a = %d b = %d\n", a, b);
return 0; }
编写代码实现:求一个整数存储在内存中的二进制中1的个数
#include<stdio.h>
int main()
{
int num = 0;
scanf("%d", &num);
int i = 0;
int count = 0;
for (i = 0; i < 32; i++)
{
if (1 == ((num >> i) & 1))
{
count++;
}
}
printf("%d\n", count);
return 0;
}