第十五章 位操作
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 int
或 unsigned 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);
网友评论