第 15 章 位操作
第十四章 位操作¶
👉【复习题】【编程练习题】¶
1. 二进制数、位和字节¶
以数字10
为基底表示的数字称为十进制数
。
以数字2
为基底表示的数字称为二进制数
。
用二进制系统
可以把任意整数表示为 0
和 1
的组合。
1.1 二进制整数¶
1字节包含8位。
C语言用字节(byte)
表示存储系统字符集所需的大小。
描述存储器芯片
和数据传输率
中所用的字节指的是 8位
字节。
1.2 有符号整数¶
如何表示有符号整数取决于硬件,而不是C语言。
二进制补码
方法
二进制反码
方法通过反码位组合中的每一位形成一个负数。
2. 其他进制数¶
2.1 八进制¶
八进制是指八进制记数系统。
将八进制数
转换为二进制
形式时,不能去掉中间的0。
2.2 十六进制¶
十六进制:十六进制记数系统。
每个十六进制都对应一个4位的二进制数(即4个二进制数)。
十六进制很适合表示字节值。
3. C按位运算符¶
C提供按位逻辑运算符
和 移位运算符
。
3.1 按位逻辑运算符¶
-
二进制反码或按位取反:~
一元运算符
~
把 1 变为0,把0变为1。 -
按位与:
&
二元运算符
&
通过逐位比较两个运算对象,生成一个新值。对于每个位,只有两个运算对象中相应的位都为1时,结果才为1(从真/假方面来看,只有当两个位都为真时,结果才为真)。
掩码:按
位与
运算符常用于掩码(mask)
。一些设置为开(1)
或关(0)
的位组合。关闭位(清空位):和打开特定的位类似,使用
&
,任何位与1组合都得本身(保持1号位不变,改变其他各位)。任何位与0组合都得0。 -
按位或:
|
二元运算符
|
,通过逐位比较两个运算对象,生成一个新值。对于每个位,如果两个运算对象中相应的位只有一个1(非两个为1),结果为1(从真/假考虑,有一个位为真且不是为同为1,那结果为真)。
打开位(设置位):使用
按位或(|)
运算符,任何位与0组合,结果都为本身;任何位与1组合,结果都为1。 -
按位异或
^
二元运算符
逐位比较两个运算对象。
对于每个位,如果一个运算对象中相应的位一个为1(但不是两个都为1),结果为1(真假来看,如果两个运算对象中相应的一个位真且不是两个同为1,结果为真)。
切换位:打开已关闭的位,或关闭已打开的位。可以使用
按位异或
运算符完成。
3.2 移位运算符¶
-
左移
<<
将其
左侧运算对象
每一位的值向左移动
其右侧运算
对象指定的位数
。左侧运算对象移出左末端位的值丢失,用0填充空出的位置。
-
右移
>>
将其左侧运算对象每一位的值向右移动其右侧运算对象指定的位数。
左侧运算对象移出,右末端的值丢。
对于无符号类型,用0填充空出的位置。
对于有符号类型,其结果取决于机器。空出的位置可用0填充,或者用符号位(即最左端的位)的副本填充。
每个位向右移动两个位置,空出的位用0填充。
总结:
运算符 | 说明 |
---|---|
number << n | number 乘以2的n次幂 |
number >> n | 如果number为非负,则用number除以2的次幂 |
4. 位字段¶
位字段(bit field):一个signed int 或 unsigned int 类型变量中一组相邻的位(C99和C11新增_Bool类型的位字段)
通过 结构声明
来建立。此结构声明为每个字段提供标签,并确定字段的宽度。
通过普通的结构成员运算符(.)单独给字段赋值。
内含位字段的结构允许在一个存储单元中存储多个设置。
5. 对齐特性(C11)¶
对齐:如何安排对象在内存中的位置。
_Alignof 运算符
给出一个类型的对齐要求,在关键字 _Alignof
后面的圆括号中写上类型名
即可。
使用
_Alignas说明符
指定一个变量
或类型的对齐值
。不应该要求该值小于基本对齐值。