C语言原码、反码、补码
一、原码、反码、补码
1.原码:直接将数值按照正负数的形式翻译成 ⼆进制 得到的就是原码。
2.反码:将原码的符号位不变,其他位依次按位取反就可以得到反码。
3.补码:反码+1 就得到补码。
总结:
1.原码 --> 补码 : 取反+1
2.补码 --> 原码 : 取反+1
二者转换是一样的。
对于整形来说:数据存放内存中其实存放的是补码。
二、位操作符
注:以下的操作数必须都是整数
&
:按位与 两数 补码 按位相比,有0则为0,同1才为1|
:按位或 两数 补码 按位相比,有1则为1,同0才为0^
:按位异或 两数 补码 按位相比,相同为0,相异为1~
:按位取反 对一个 补码 ,把0变1,把1变0
#include <stdio.h>
int main()
{
int num1 = -3;
int num2 = 5;
printf("%d\n", num1 & num2);
printf("%d\n", num1 | num2);
printf("%d\n", num1 ^ num2);
printf("%d\n", ~0);
return 0;
}
下面让我们来分析一下:
num1:1000 0011 --> 补:1111 1101
num2:0000 0101 --> 补:0000 0101
num1 & num2:0000 0101 --> 5
num1 | num2:1111 1101 --> 1000 0011 --> -3
num1 ^ num2:1111 1000 --> 1000 1000 --> -8
三、经典面试题
例1:不能创建临时变量(第三个变量),实现两个整数的交换。
这道题,如果可以创建变量,那简单无比。但这道题堵死了这条路emmmm……
首先,先引入两个公式:
a ^ a = 0
a ^ 0 = 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", a, b);
return 0;
}
上述代码中,先把 a ^ b
赋给了 a
,那么 b = a ^ b = (a ^ b) ^ b = a ^ (b ^ b) = a ^ 0 = a
,很自然地把 a 赋给了 b。
最后一个 a = a ^ b = (a ^ b) ^ a = (a ^ a) ^ b = b
。
进而完成交换。这道题可以背下来当作积累。