C Primer Plus(十五)

摘要:
第15章比特操作15.1二进制数、比特和字节以2为基数表示的数字称为二进制数。任何整数都可以用二进制数表示为1和0的组合。这个系统非常适合数字计算机。这些运算符被称为位运算符,因为它们在不影响左右位的情况下对每个位进行操作。位字段由结构声明创建,该结构声明为每个字段提供标签并确定字段的宽度。
第十五章 位操作

15.1 二进制数、位和字节

以2为基数表示的数字称为二进制数,可以使用二进制数将任何整数表示为1和0的一个组合,这种系统非常适合于数字计算机使用。

15.1.1 二进制整数

描述存储器芯片和数据传输率时使用的字节指8位字节。
最小的二进制数是00000000,或一个简单的0.一个字节可以存储的数的范围是0到255.
通过改变对位模式的解释方式,一个字节可以存储从-128到+127之间的整数。

15.1.2 有符号整数

有符号数的表示方法是由硬件决定,而不是由C决定。其中最简单的方法就是保留1位来表述数的符号。
但是该方法有一个确定就是有两个零+0和-0.
二进制补码避免了这个问题。
两种方法的区别在于确定该负数值的方法。从一个9位组合100000000减去一个负数的位组合,结果是该负数值的数量。
例如一个负数的位组合为10000000,值为100000000-10000000 即10000000 128,因此该数为-128. 同理10000001是-127,11111111是-1.

15.1.3 二进制浮点数

浮点数分两部分存储:一个二进制小数和一个二进制指数。
像1/3这样的许多小数不能用十进制计数法精确的表示。同样,许多小数也不能用二进制计数法精确表示。
要在计算机中表示一个浮点数,需要留出若干位存放一个二进制小数,其它位存放一个指数。

15.2 C的运算符

15.2.1 位逻辑运算符

4个位运算符用于整形数据,包括char。这些运算符称为位运算符的原因是它们对每位进行操作,而不影响左右两侧的位。

一、二进制反码或按位取反:~

一元运算符~将每个1变为0,每个0变为1.

二、位与:&

二进制运算符&通过对两个操作数逐位进行比较产生一个新值。对于每个位,只有两个操作数的对应位都为1时结果才为1.

三、位或:|

二进制运算符&通过对两个操作数逐位进行比较产生一个新值。对于每个位,如果其中任意操作数中对应的位为1时结果为1.

四、位异或^

二进制运算符&通过对两个操作数逐位进行比较产生一个新值。对于每个位,如果操作数中对应的位有一个为1(但是不都为1)那么结果为1.

15.2.2 用法:掩码

“位与”运算符通常跟掩码一起使用。掩码是某些位设为开而某些位设置为关的位组合。
假设定义符号常量MASK为2,即二进制的00000010,只有位1是非零。
那么flags&=MASK;这个语句将导致flags的除位1之外的所有位都被设为0.
因为掩码中的零覆盖了flags中相应的位,所以该过程成为“使用掩码”。

15.2.3 用法:打开位

有时,您可能需要打开一个值中特定的位,同时保持其它位不变。
例如,MASK其位1设为1,下列语句中将flags中的位1设为1,并保留其它所有位不变:flags|=MASK;

15.2.4 用法:关闭位

有时,您可能需要关闭一个值中特定的位,同时保持其它位不变。
例如,MASK其位1设为1,下列语句中将flags中的位1设为0,并保留其它所有位不变:flag&=~MASK;

15.2.5 用法:转置位

转置一个位表示如果该位打开则将其关闭,否则将其打开。
该值中对应掩码位为1的位被转置,对应掩码位为0的位则不改变。flag^=MASK;

15.2.6 用法:查看一位的值

假设您希望查看一位的值。例如flag的位1是否为1?
if((flag&MASK)==MASK)

15.2.7 移位运算符

一、左移

左移运算符<<将其左侧操作数的值的每位向左移动,移动的位数由其右侧操作数指定。空出的位用0填充,并且丢弃移出左侧操作数末端的位。(10001010)<<2  ----00101000

二、右移

左移运算符<<将其左侧操作数的值的每位向左移动,移动的位数由其右侧操作数指定。丢弃移出右侧操作数右端的位。对于unsigned类型,使用0填充左端空出的位。对于有符号类型,结果依赖于机器。

三、用法:移位运算符

移位运算能够提供快捷、高效的对2的幂的乘法和除法。
number<<n    //number乘以2的n次幂
number>>n   //如果number非负,则用number除以2的n次幂
例如:假设您希望使用一个unsigned long值代表颜色值,其中低位字节存放红色亮度,下一字节存放绿色亮度,第三个字节存放蓝色亮度。假设您随后希望每种颜色的亮度存储在各自的unsigned char变量中
#define BYTE_MASK 0xff
unsigned long color=0x002a162f;
unsigned char blue,green,red;
red=color&BYTE_MASK;
green=(color>>8)&BYTE_MASK;
blue=(color>>16)&BYTE_MASK;

四、用法:反转一个值中的最后n位

int invert_end(int num,int bits)
{
int mask=0;
int bitval=1;
while(bits-->0)
{
mask|=bitval;
bitval<<1;
}
return num ^mask;
}

15.3 字位段

对位进行操作的第二种方法是使用位字段,位字段是一个signed int或unsigned int中一组相邻的位。位字段由一个结构声明建立,该结构声明为每个字段提供标签,并决定字段的宽度。
例如,以下声明建立了4个1位字段:
struct{
unsigned int autfd: 1;
unsigned int bldfc: 1;
unsigned int undln: 1;
unsigned int itals: 1;
}prnt;
可以使用普通的结构成员运算符将值赋给单独的字段:例如prnt.itals=0;
因为每个字段都正好为1位,所以1和0是惟一可以用于赋值的值。变量prnt被存储在一个Int大小的存储单元中,但是在本例中仅有其中的4位被使用。
当然也可以创建不同位大小的字段。

免责声明:文章转载自《C Primer Plus(十五)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇重构的技巧linux下vi命令大全下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Linux内核学习笔记五——中断推后处理机制

一 中断硬件通过中断与操作系统进行通信,通过对硬件驱动程序处注册中断处理程序,快速响应硬件的中断。 硬件中断优先级很高,打断当前正在执行的程序。有两种情况: 硬件中断在中断处理程序中处理 硬件中断延后再进行处理 这个具体硬件相关,在中断处理程序中处理,打断了当前正在执行的程序;所有中断都将被屏蔽;如果占用时间太长不合适, 造成系统交互性,反应能力都会受到影...

aosp 制作 rom 刷机 添加厂家二进制驱动 及 出厂镜像

首先介绍下背景知识。 aosp 仅是一套源码,不含厂家驱动。 CM安卓的厂家驱动是自行提取的。 一般的安卓手机分区,有 boot , system, user , Baseband 基带,recovery , cache 等。 GooglePixel XL 都需要哪些 驱动呢? 1, 厂家驱动二进制。 https://developers.google.c...

python读取二进制文件写入到txt

import os os.chdir(r'C:UsersUsmartDesktopfile_test') fp=open("index.dat",'rb') #以只读二进制文件打开 data = fp.read() fp_txt=open("text.txt",'w') #以只读二进制文件打开 for tmp in data: writedata...

计算机基础知识:原码、反码、补码

可能很多人有这样的疑问,我们为什么要了解原码、反码、补码,它能帮助我们解决什么问题?在编写代码中有什么实际用途呢? 我是这样认为的,其一,作为计算机基础知识,我们必须有所了解。其二、这些基础知识无论是普通的编写代码,还是研究高超的算法都离不开它。 例:我们常见的位运算 按位与(&)、按位或(|)、取反(~)等等。 在代码中, 我们可能经常会碰到这样...

GBT28181中的RTP

国标中说h264数据按照RFC3984打包,但是国标的测试工具——SPVMN,却不支持RFC3984的打包方式。无奈之下直接用RFC3550的方式打包,其实就是分包,然后加上RTP头,对于一帧的结束,在RTP头中把MARK置1,并且在一帧的开始把时间戳增加而已。这种打包方式其实和RFC有冲突,打包处理的RTP数据用VLC播放解码不正常,但用SPVMN是可以...

原码,反码,补码,移位

https://www.cnblogs.com/btgyoyo/p/6371398.html 复习下二进制的有关知识 1.所有的数据都是以二进制的形式存储在硬盘上。对于一个字节的8位到底是什么类型 计算机是如何分辨的呢? 其实计算机并不负责判断数据类型,数据类型是程序告诉计算机该如何解释内存块. 2.对于字符的存储,先将字符转化成其字符集的码点,(码点就是...