zoukankan      html  css  js  c++  java
  • C Primer Plus(十五)

    第十五章 位操作

    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位被使用。
    当然也可以创建不同位大小的字段。

  • 相关阅读:
    架构设计的UML图形思考
    SymmetricDS文档翻译--【Chapter 3. 具体配置(Configuration)[section C]】
    LeetCodeOJ. String to Integer (atoi)
    jquery05 继承
    jquery 04
    jquery constructor(null)
    jquery js解析函数、函数直接调用
    jquery init 关系
    jquery constructor
    jQuery03
  • 原文地址:https://www.cnblogs.com/tuifeideyouran/p/3132471.html
Copyright © 2011-2022 走看看