操作符的分类
算术操作符
移位操作符
位操作符
赋值操作符
单目操作符
关系操作符
逻辑操作符
条件操作符
逗号表达式
下标引用、函数调用和结构成员
算术操作符
+ - * / %
- 除了 % 操作符之外,其他的几个操作符可以作用于整数和浮点数。
- 对于 / 操作符如果两个操作数都为整数,执行整数除法。而只要有浮点数执行的就是浮点数除法。
- % 操作符的两个操作数必须为整数。返回的是整除之后的余数。
int main()
{
int a = 3 / 5;
printf("%d", a);
return 0;
}
结果是0,因为a是整型变量
那么我想问,如果是这样呢
int main()
{
float a = 3 / 5;
printf("%f", a);
return 0;
}
我们来看结果
其实这里应该这样子理解,是先3/5得到一个数字,放在了a里面,因为3和5都是整数,所以自动进行整数的运算,如果真的想要小数的话
需要除号的两端至少有一个小数
int main()
{
float a = 3.0 / 5.0;
printf("%f", a);
return 0;
}
移位操作符
<< 左移操作符
>> 右移操作符
注:移位操作符的操作数只能是整数。
int main()
{
int a = 2;
//把a的二进制位向左移动一位
int b = a << 1;
printf("%d", b);
return 0;
}
我们一起来看一下,整型变量,四个字节,三十二个比特位,所以a的二进制真值就应该是
00000000 00000000 00000000 00000010
我们向左移动一位(这里实际上是全部的二进制码向左移动一位,左边的不要,右边加个0)
00000000 00000000 00000000 00000100
所以b的值转换为2进制就应该是4
我们来看结果
左移操作符,左边丢弃,右边补0;
右移
int main()
{
int a = 10;
//把a的二进制位向右移动一位
int b = a >> 1;
printf("%d", b);
return 0;
}
a的真值就是
00000000 00000000 00000000 00001010
右移一位
-
算数右移
右边丢弃,左边补原符号位
-
逻辑右移
右边丢弃,左边补0
00000000 00000000 00000000 00000101
所以呢这里应该是5
我们使用的是算数右移还是逻辑右移呢?
我们一起来测试一下
int main()
{
int a = -1;
//把a的二进制位向右移动一位
int b = a >> 1;
printf("%d", b);
return 0;
}
这里还是-1,说明计算机采用的是算数右移
这里为什么是-1而不是0呢?
计算机在存储整数使用的是补码,所以-1的补码是
11111111 11111111 11111111 11111111
右移之后再补符号位依旧是这个,所以右移之后输出的依然是-1
警告⚠ :
对于移位运算符,不要移动负数位,这个是标准未定义的。
int num = 10;
num>>-1;//千万不要这么写,这么写编译器都看不懂
位操作符
& //按位与 全真为真
| //按位或 有真为真
^ //按位异或 相异为真
注:他们的操作数必须是整数。
按位与
int main()
{
int a = 3;
int b = 5;
int c = a & b;
//
//a的二进制真值 00000000 00000000 00000000 00000011
//b的二进制真值 00000000 00000000 00000000 00000101
//按位与 00000000 00000000 00000000 00000001
printf("%d", c);
return 0;
}
我们看一下结果
按位或
int main()
{
int a = 3;
int b = 5;
int c = a | b;
//
//a的二进制真值 00000000 00000000 00000000 00000011
//b的二进制真值 00000000 00000000 00000000 00000101
//按位或 00000000 00000000 00000000 00000111
printf("%d", c);
return 0;
}
按位异或
int main()
{
int a = 3;
int b = 5;
int c = a ^ b;
//
//a的二进制真值 00000000 00000000 00000000 00000011
//b的二进制真值 00000000 00000000 00000000 00000101
//按位异或 00000000 00000000 00000000 00000110
printf("%d", c);
return 0;
}
面试题
如何交换两个变量的值,不能使用第三个变量,即a=3,b=5,交换后a=5,b=3?
先思考一分钟
一般来说,我们都是这样子实现的
c = a;
a = b;
b = c;
揭晓答案
方法1:
a = a + b;
b = a - b;
a = a - b;
但是这种方法其实有缺陷,如果数值太大是有可能出现溢出的情况的
方法2:
异或
a = a ^ b;
b = a ^ b;
a = a ^ b;
我们先来验证一下
int main()
{
int a = 3;
int b = 5;
printf("a = %d b = %d\n", a, b);
a = a ^ b;
b = a ^ b;
a = a ^ b;
printf("a = %d b = %d\n", a,b);
return 0;
}
我们来简单分析一下
a = 3 二进制 011
b = 5 二进制 101
a = a ^ b; 110
b = a ^ b; 011
a = a ^ b; 101
a = 5 二进制 101
b = 3 二进制 110
我们其实可以这样子理解
我们把a和b进行按位或,也就是说我们通过a和b生成了一个密码,这个密码由a和b得到
我们使用b进行译码,就能得到a
我们使用a进行译码,就能得到b
好,那么今天先到这,剩下的操作符明天再说