1. 操作符分类:
算术操作符: + - * / %
移位操作符: << >>
位操作符: & | ^
赋值操作符: = += -= *= /= ……
单目操作符: ! sizeof + - ~ & *
关系操作符: > < >= <= == !=
逻辑操作符: && ||
条件操作符: ? :
逗号操作符: ,
下标引用、函数调用和结构成员: [] () . ->
2. 算术操作符
(注:除了 % 操作符之外,其他的几个操作符可以作用于整数和浮点数)
+ : 加法运算
- : 减法运算
* : 乘法运算
/ : 除法运算,除数不能为0
分为:
1. 整数除法(除号两端都是整数)
2. 浮点数除法(除号两端只要有一个小数就执行浮点数除法)
% : 取模操作符,得到的是整除后的余数
1. 得到的是整除后的余数
2. %取模操作符的两个操作数必须是整数
3. 移位操作符
(注:移位操作符的操作数只能是整数,对于一位运算符,不要移动负数位,这是标准未定义的,计算结果将取决于编译器,结果不可预料)
补充:整数的二进制表示形式
有三种表现形式:
原码 | 反码 | 补码
1. 正整数的原码、反码、补码是相同的
2. 负整数的原码、反码、补码是要计算的
3. 不管是正整数还是负整数都可以写出二进制原码
4. 根据正负直接写出的二进制序列就是原码
5.移位移动的是二进制信息
6.整数在内存中存储的是补码
7.计算的时候也是使用补码计算的
(演示代码:)
#include <stdio.h> //不管是正整数还是负整数都可以写出二进制原码 //根据正负直接写出的二进制序列就是原码 int main() { //1个整型是4个字节 = 32个bit位 //符号位是 1 表示负数 //符号位是 0 表示正数 int a = 15; //正整数的原码、反码、补码是相同的 //00000000000000000000000000001111 -- 原码 //00000000000000000000000000001111 -- 反码 //00000000000000000000000000001111 -- 补码 int b = -15; //负整数的原码、反码、补码是要计算的 //10000000000000000000000000001111 -- 原码 //11111111111111111111111111110000 -- 反码(原码的符号位不变,其它位按位取反得到的就是反码) //11111111111111111111111111110001 -- 补码(反码 +1 就是补码) return 0; }
<< : 左移操作符 -- 补码 左边丢弃,右边补0
//左移操作符:补码 左边丢弃,右边补0 #include <stdio.h> int main() { //正整数: int a = 6; // 00000000000000000000000000000110 -- 正整数的 原码、反码、补码 相同 // 00000000000000000000000000000110 -- 补码 (移位操作的是 补码) //左移后: // 0 0000000000000000000000000000110 0 -- 补码 (原码 、 反码) // 因为正整数的 原码、反码、补码 相同,所以这也是原码 int b = a << 1; printf("%d\n", b); printf("%d\n", a); //负整数: int c = -6; // 10000000000000000000000000000110 -- 原码 // 11111111111111111111111111111001 -- 反码 (原码按位取反) // 11111111111111111111111111111010 -- 补码 (反码 +1 ) int d = c << 1; //左移后: // 1 1111111111111111111111111111010 0 -- 补码 // 11111111111111111111111111110011 -- 反码 (补码 -1) // 10000000000000000000000000001100 -- 原码 (符号位不变,反码按位取反) // -12 printf("%d\n", d); printf("%d\n", c); a = a << 1; // 也可以写成: a <<= 1; //符合符号 <<= :左移等于 ,类似 a += 1 return 0; }
>> : 右移操作符
分为:
1. 算术 右移 (补码 右边 丢弃, 左边 补原来的符号位)
2.逻辑 右移 (补码 右边 丢弃, 左边 直接补0)
(C语言没有明确规定到底是算术右移还是逻辑右移,一般编译器上采用的是算术右移)
#include <stdio.h> int main() { //正整数: int a = 15; //00000000000000000000000000001111 -- 补码 int b = a >> 1; // 0 0000000000000000000000000000111 1 -- 补码(移位后) //C语言没有明确规定到底是算术右移还是逻辑右移,一般编译器上采用的是算术右移 printf("%d\n", b); //算术右移 // b 得到的是 a 移位后的结果 // 算术右移(右边丢弃,左边补原来的符号位) // 从 二进制的1111 变成 二进制的111 ,从 十进制的 15 变成了 十进制的 7 printf("%d\n", a); // a >> 1,进行移位后,a没有发生变化, // 表达式不会影响 a 的 值 //负整数: int c = -15; //11111111111111111111111111110001 -- 补码 (符号位是 1 表示负数) int d = c >> 1; // 1 1111111111111111111111111111000 1 -- 补码 (移位后) // 空出的位置补的是 1 ,说明是算术右移(右边丢弃,左边补原来的符号位) // 实际值是用 原码 表示的 printf("%d\n", d); //算术右移 // 反码 +1 就是补码 ,补码 -1 就是反码: // 11111111111111111111111111110111 -- 反码 // 原码的符号位不变,反码按位取反得 原码 // 10000000000000000000000000001000 -- 原码 (-8) printf("%d\n", c); return 0; }
(有类似 除以2向下取整 的效果)
4.位操作符
(注:位操作符的操作数必须是整数)
1.整数在内存中存储的是补码
2.计算的时候也是使用补码计算的
& : 按(二进制)位与 -- 对应二进制位有0则为0,两个同时为1,才为1
//位操作符 #include <stdio.h> int main() { int a = 3; // 00000000000000000000000000000011 -- 补码(正整数的原码、反码、补码相同) int b = -5; // 10000000000000000000000000000101 -- 原码 // 11111111111111111111111111111010 -- 反码 // 11111111111111111111111111111011 -- 补码 int c = a & b; // & -- 对应二进制位有0则为0,两个同时为1,才为1 // 00000000000000000000000000000011 -- a补码 // 11111111111111111111111111111011 -- b补码 // 得: // 00000000000000000000000000000011 -- 补码(两个补码计算出来的也是补码) // 这里计算出来的结果符号位是 0 ,说明是 正整数,三个码相同,所以这也是原码 printf("%d\n", c); // 所以结果是3 return 0; }
按(二进制)位或 -- 对应二进制位有1则为1,两个同时为0,才为0
//位操作符 #include <stdio.h> int main() { int a = 3; // 00000000000000000000000000000011 -- 补码(正整数的原码、反码、补码相同) int b = -5; // 10000000000000000000000000000101 -- 原码 // 11111111111111111111111111111010 -- 反码 // 11111111111111111111111111111011 -- 补码 int c = a | b; // | -- 按(二进制)位或 -- 对应二进制位有1则为1,两个同时为0,才为0 // 00000000000000000000000000000011 -- a补码 // 11111111111111111111111111111011 -- b补码 // 得: // 11111111111111111111111111111011 -- 补码(两个补码计算出来的也是补码) // // 这里计算出来的结果符号位是 1 ,说明是 负整数,还要计算 反码 和 补码 // 11111111111111111111111111111010 -- 反码 // 10000000000000000000000000000101 -- 原码 printf("%d\n", c); // 所以结果是-5 return 0; }