C/C++按位取反操作详解
按位取反:~
按位取反运算符 ~ 会将二进制位中的 1 变为 0,0 变为 1。
原码、反码和补码
- 原码:最高位是符号位,0 表示正数,1 表示负数。
- 反码:最高位是符号位,0 表示正数,1 表示负数。正数的反码是它本身,负数的反码是除了符号位以外其余各位取反。
- 补码:最高位是符号位,0 表示正数,1 表示负数。正数的补码是它本身,负数的补码是反码 +1。
为什么需要补码操作
例如:1 + (-1) = 0
- 如果使用原码直接计算:0001 + 1001 = 1010,结果是 -2,这是错误的。
- 如果使用补码计算:0001 + 1111 = 1 0000,最高位的 1 溢出,结果是 0000,即 0。
原码和补码的转化方式
- 补码转原码:正数不变,负数除了符号位以外,其余各位取反 +1。
- 原码转补码:正数不变,负数除了符号位以外,其余各位取反 +1。
为什么 10 取反之后会变为 -11
计算机中存储方式都是按照补码的形式存储的。正数的补码是它本身,负数补码等于反码 +1。
所以 10 对应的二进制是 0000 1010,取反之后 1111 0101。最高位是 1,代表符号位,说明这个数是负数。这是补码,如果要拿到十进制的结果,必须将其转化为原码才能看到。原码是补码取反 +1 得来的,所以原码除了符号位以外,各位取反 +1 获取:1000 1010 + 1 = 1000 1011,这个值就是 -11。
C 语言表示
#include <stdio.h>
int main() {
// 1. 无符号字符型变量的按位取反
unsigned char ch = 0; // 定义无符号字符型变量 ch,初始值为 0
// unsigned char 是 8 位无符号整数(范围 0~255),没有符号位,所有位都用于表示数值
// 此时 ch 的 8 位二进制为:0000 0000(每一位都是 0)
ch = ~ch; // 对 ch 进行按位取反操作(~是按位取反运算符)
// 按位取反规则:二进制的每一位 0 变 1,1 变 0
// 原来的二进制:0000 0000
// 取反后变为:1111 1111(8 位全是 1)
// 对于无符号数,11111111 转换为十进制是 255(计算:128+64+32+16+8+4+2+1=255)
printf("%d\n", ch); // 打印 ch 的值,输出 255
// 2. 有符号整型变量的按位取反
int number = ;
number = ~number;
(, number);
;
}


