三,位操作


3.1 二进制数,位,和字节

计算机中的存储器芯片和数据传输率中的 一、1字节 = 8位
C字节可能是8位,9位,16位或其它。
这里以1字节 = 8位 (八位组) 为例。

3.2 二进制整数

1字节可以存储 0~255 范围内的无符号整数和 -127(-128) ~127 范围内的有符号整数。

3.2.1 有符号整数

用一位存储符号,剩下七位存储数字。
缺点是会存在 +0 (00000000) 和 -0 (10000000) ,易混淆。

有符号整数

3.2.2 二进制补码

在负值上和上方有区别,详情见图。

二进制补码

3.3.3 二进制反码

反转每一位形成该整数的负数。
也会存在+0 (00000000) 和 -0 (11111111)。
能表示 -127~127范围内的整数。

3.3 二进制浮点数

浮点数分 二进制小数 和 二进制指数 储存。

3.3.1 二进制小数

0.527=5/10+2/100+7/1000

但在二进制中会被表示为 .101 :

1/2+0/4+1/8=0.625

因此许多分数不能被精准表示。

3.3.2 浮点数表示法

用若干位表示二进制分数,其他位储存指数。
数字的实际值是由 二进制小数 乘以 2的指定次幂 组成。

3.4 其它进制数

3.4.1 八进制

每三个二进制位对应一个八进制位。例如:

(1111111)_2 = (337)_8

比0337大的八进制数要用多个字节表示。

3.4.2 十六进制

每四个二进制位对应一个十六进制位。

3.5 C 按位运算符

3.5.1 按位逻辑运算符

  1. 按位取反 ~
    作用:把1变成0,0变成1
  2. 按位与 &
    作用:比较两个运算对象,两个位均为1时,结果为1
    &= 同时按位与和赋值
  3. 按位或 |
    作用:比较两个运算对象,有一位为1,结果为1
    |= 同时按位或和赋值
  4. 按位或与 ^
    作用:比较两个运算对象,一位为1,另一位为0,结果为1
    ^= 同时按位或与和赋值

3.5.2 用法

3.5.2.1 掩码(MASK)

  1. 打开位

    flags |= MASK

    MASK中为1的位,flags对应的位为1
    MASK中为0的位,flags对应的位不变

  2. 关闭位

    flags &= ~MASK

    MASK中为1的位,flags对应的位为0
    MASK中为0的位,flags对应的位不变

  3. 切换位

    flags ^= MASK
    MASK中为1的位,flags对应的位变化
    MASK中为0的位,flags对应的位不变

3.5.2.2 位移运算符

flags >> n 将所有位右移n位
flags << n 将所有位左移n位

3.5.3 位字段

支持 signed int 和 unsigned int 变量
使用 struct{}

struct {                       //num 包含3个2位的字段。
    unsigned int num1 : 2;
    unsigned int num2 : 2;
    unsigned int num3 : 2;
} num;

//用 . 赋值,因为只有两位,只能存储 0~3 的数字。
num.num1 = 3
num.num2 = 0
num.num3 = 2