操作符的分类
移位操作符: << >>位操作符: & | ^算术操作符: + 、- 、* 、/ 、%
赋值操作符: = 、+= 、 -= 、 *= 、 /= 、%= 、<<= 、>>= 、&= 、|= 、^=单⽬操作符: !、 ++ 、 -- 、 & 、 * 、 + 、 - 、 ~ 、 sizeof 、 ( 类型 )关系操作符: > 、 >= 、 < 、 <= 、 == 、 !=逻辑操作符: && 、 ||条件操作符: ? 、:逗号表达式: ,下标引⽤: [ ]函数调⽤: ()结构成员访问: . 、 ->
1.原码,反码,补码
整数的二进制表示方法有的三种:原码,反码,补码
有符号整数的三种表示方法均由俩部分组成:符号位,数值位。二进制的最高位就是符号位,其余的都是数值位
正整数的原,反,补码表示方法都一样
负数的三种表示方法各不相同
原码:直接将数字翻译成二进制的形式放进数值位,在根据正负号判断数值位
反码:符号位不变,数值位依次取反(1变成0 0变成1)
补码:在反码的基础上+1
整数放在内存中的就是补码
why?在计算机系统中,数值⼀律⽤补码来表⽰和存储。原因在于,使⽤补码,可以将符号位和数值域统⼀ 处理;同时,加法和减法也可以统⼀处理(CPU只有加法器)此外,补码与原码相互转换,其运算 过程是相同的,不需要额外的硬件电路。
虽然说cpu只有加法器,但是这并不意味着减法就做不到了
例如:1 - 1
使用原码计算
1 - 1 cpu通常会等效于1 + (-1)来计算,如果这时候用原码进行计算就会出错:
计算结果显然是错位的
![](https://img-blog.csdnimg.cn/direct/e643c60b9bc54b26a767e6fb99450f0b.png)
结论
我们在进行计算时用到的是补码,整数在内存中储存的也是补码。(正整数原 ,补 ,反 码一样)
2.移位操作符
2.1 << 左移操作符
移位规则:左边抛弃、右边补0
#include<stdio.h>
int main() {
int num = 10;
int n = num << 1; //num的值并不会该变,相当于:
//a = b + 4 b的值不会被改变一样
printf("%d ", num);
printf("%d ", n);
return 0;
}
输出结果: 10 20
2.2 >> 右移操作符
>> 右移操作符
移位规则:1.逻辑右移:左边⽤0填充,右边丢弃
2.算术右移:左边⽤原该值的符号位填充,右边丢弃
注:大部分编译器用的都是算数右移
int main() {
int num = -1;
int n = num >> 1;
printf("%d ", num);
printf("%d ", n);
return 0;
}
输出结果:-1 -1
逻辑右移
算数右移
int num = 10;
num>>-1;//error
有趣的现象
int main() {
int n = 2;
int nn = n << 1;
int nnn = nn << 1;
printf("%d ", n);
printf("%d ", nn);
printf("%d ", nnn);
return 0;
}
输出结果 2 4 8
当我们使用<<左移操作符进行操作时,我们可以发现:
每移动一位,移动后的数,是移动前 × 2的结果
可以简单理解:当我们使用左移操作符进行位移时,移动一位,就有 × 2的效果
移动两位,就有 × 2 × 2的效果.......依次类推
3.位操作符:&、|、^、~
& | 按位与 | 两个整数的二进制补码比较:有0为0,俩个1才为1 |
| | 按位或 | 两个整数的二进制补码比较:有1为1,俩个0才为0 |
^ | 按位异或 | 两个整数的二进制补码比较:相同为0,相异为1 |
~ | 按位取反 | 一个整数的二进制补码进行该变:1变0,0变1 |
练习1
不创建临时变量(第三个变量),实现对两个数的交换
解题要点
要点一:任何整数 ^ (按位异或)自己,都等于0
int main()
{
int a = -5;
int b = 5;
a = a ^ a;
b = b ^ b;
printf("a = %d b = %d",a,b);
return 0;
}
输出结果:a = 0 b = 0
要点二:任何整数 ^(按位异或)0 ,都等于自己
看懂这两个要点后,下面的代码就很好理解了 :
#include <stdio.h>
int main()
{
int a = 10;
int b = 20;
a = a^b;
b = a^b; //b = (a^b)^b b = a这时,b的值就已经换成a了,b = 10
a = a^b; //a = (a^b)^a a = b 这里的b是由 a = a^b;替换的
//所以它里面b的值还是20,所以a = 20
printf("a = %d b = %d\n", a, b);
return 0;
}