第十五章 位操作——《C Primer Plus》笔记

第十五章 位操作

15.1 二进制数、位和字节

二进制数(binary number):以 2 为基底表示的数字。

C 语言用字节表示存储系统字符集所需的大小,所以 C 字节可能是 8 位,9 位,16 位或其他值。通常为 8 位。

二进制补码(two's-complement):

  • 正数的高位为 0:表示正数,低七位表示数值;
  • 负数的高位为 1:表示负数,低七位各取反加一表示负值的量。

一个二进制补码的相反数,各位取反加一,因为不是对称的。

0 - 127,-128 - -1

二进制小数

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

15.2 其他进制数

八进制,十六进制

15.3 C 按位运算符

  • 按位运算符

  • 按位取反:~

  • 按位与:&

  • 按位或:|

  • 按位异或:^

用法

  • 掩码

    一些设置为开或关的位组合。

  • 设置位

    打开一个值中的特定位,同时保持其他位不变。

    flag |= mask

  • 关闭位

    关闭一个值中的特定位,同时保持其他位不变。

    flag &= ~mask

  • 切换位

    切换一个值中的特定位的开关状态,同时保持其他位不变。

  • 检查位的值

    flag &= mask

移位运算符

  • 左移:<<

  • 右移:>>

15.4 字段

位字段(bit field):signed intunsigned int 类型变量中的一组相邻的位。

struct
{
  unsigned int field1 : 1;
  unsigned int        : 2;
  unsigned int field2 : 1;
  unsigned int        : 0;
  unsigned int field3 : 1;
}
  • 总位数超出一个 unsigned int 类型,会用到下一个 unsigned int 类型的存储位置。
  • 一个字段不允许跨越两个 unsigned int 之间的边界,会自动移动跨界的字段,保持 unsigned int 的边界对齐。
  • 可以用未命名的字段宽度填充未命名的洞。
  • 使用一个宽度位 0 的未命名字段迫使下一个字段与下一个整数对齐。

15.5 对齐特性(C11)

_Alignof 给出一个类型的对齐要求。

_Alignas 指定一个变量或类型的对齐值。

_Alignas(double) char c1;
_Alignas(8) char c2;
unsigned char _Alignas(long double) c_arr[sizeof(long double)];

C11 还在 stdlib.h 库中添加了一个新的内存分配函数,用于动态分配的内存。

void *aligned_alloc(size_t alignment, size_t size);
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容