操作符详解
1. 操作符分类
操作符分为以下几种:
算术操作符
移位操作符
位操作符
赋值操作符
单目操作符
关系操作符
逻辑操作符
条件操作符
逗号表达式
下标引用、函数调用和结构成员
2. 算术操作符
算术操作符:
+ 加法
- 减法
* 乘法
/ 除法
% 取模(取余)操作符
int main()
{
int a = 0;
int b = 0;
scanf("%d %d", &a, &b); //输入两个数
printf("%d+%d =%d\n", a, b, a + b); //加法
printf("%d-%d =%d\n", a, b, a - b); //减法
printf("%d*%d =%d\n", a, b, a * b); //乘法
printf("%d/%d =%d\n", a, b, a / b); //除法
printf("%d%%d =%d\n", a, b, a % b); //取模
return 0;
}
int main()
{
double a = 5 / 2; //执行整数除法,得到的会是整型的值
//我们只需要调整操作数,就可以进行浮点数计算了
double b = 5.0 / 2;
double c = 5 / 2.0;
printf("a = %lf\n", a);
printf("b = %lf\n", b);
printf("c = %lf\n", c);
return 0;
}
对于取模操作符来说,用浮点型当作操作数,是错误的:
- 除了 % 操作符之外,其他的几个操作符可以作用于整数和浮点数。
- 对于 / 操作符如果两个操作数都为整数,执行整数除法,而只要有浮点数执行的就是浮点数除法。
- % 操作符的两个操作数必须为整数。返回的是整除之后的余数。
3. 移位操作符
<< 左移操作符
>> 右移操作符
1.移位操作符移的是该操作数的二进制位。
2.移位操作符的操作数只能是整数。
3.1 左移操作符
代码演示:
int main()
{
int num = 10;
printf("%d", num << 1); //将num左移一位
return 0;
}
运行结果:
图解左移操作符:
我们需要注意的是:
1.左移操作符有乘2的效果!
2.左移操作符的规则是:左边丢弃、右边补0。
3.实际上num在没有赋值的情况下,自身的值不会变化。
3.2 右移操作符
首先右移运算分两种 :
- 逻辑移位
左边用0填充,右边丢弃- 算术移位
左边用原该值的符号位填充,右边丢弃
算术右移:
int main()
{
int num = 10;
int b = num >> 1;
printf("b=%d", b); //num的值在没有赋值的情况下,自身值没有改变
return 0;
}
运行结果:
图解算术右移:
逻辑右移:
int main()
{
int num = -1;
int b = num >> 1;
printf("%d", b);
return 0;
}
解析:
如果是逻辑右移,左边补0的话,正数的原码反码补码相同,我们将得到一个非常大的值。
图解逻辑右移:
tips:
1.右移操作符有除2的效果!
负数的一位操作,移动的是该负数二进制补码
2.在我们日常大多数编译器下,运用的都是算数右移。不论在什么时候是用算术右移还是逻辑右移,这得取决于编译器。
我们在使用移位操作符时,还需要注意一点,不要移动负数位,这个是标准未定义的!
例如:
int main()
{
int a = 10;
int b = a >> -1; //error
return 0;
}
3.3 原码 反码 补码
刚讲到了-1在内存中是以补码的形式储存的,在内存中正数的原码反码补码是相同,而负数在内存中存储的是补码。需要我们转换才能得到,这里我们不得不了解整数的二进制表示方式:
整数的二进制表示形式(原反补):
原码:直接根据数值写出的二进制序列,即为原码;
反码:原码的符号位不变,其他位置按位取反,即为反码;
补码:反码 + 1,即为补码。(内存中存放的就是补码)
4. 位操作符
位操作符:
& 按位与
| 按位或
^ 按位异或
注意:
1.他们的操作数必须为整数。
2.位操作符操作的是二进制位的补码
。
4.1 按位与
代码演示
#include <stdio.h>
int main()
{
int a = 10;
int b = 11;
int c = a & b;
printf("%d", c);
return 0;
}
运行结果:
图解按位与:
运算逻辑是:两个为1(真)才为1(真),有0(假)则为0(假)。
4.2 按位或
代码演示
#include <stdio.h>
int main()
{
int a = 10;
int b = 11;
int c = a | b;
printf("%d", c);
return 0;
}
运行结果:
图解按位或:
运算逻辑:有1(真)则为1(真),无1(真)则为0(假)。
4.3 按位异或
代码演示
#include <stdio.h>
int main()
{
int a = 10;
int b = 11;
int c = a ^ b;
printf("%d", c);
return 0;
}
运行结果:
图解按位异或:
运算逻辑:相同为0(假),相异为1(真)。
任何两个相同的数按位异或得到的结果为0。
小练习:不创建临时变量(第三个变量),实现两个数的交换。
#include <stdio.h>
int main()
{
int a = 10;
int b = 20;
a = a^b; //a=10^20=30
b = a^b; //b=30^20=10
a = a^b; //a=30^10=20
printf("a = %d b = %d\n"