第12章位运算C语言除了具有高级语言的功能以外,其一个重要特点是具有某些低级语言的功能,这主要表现在C语言有系统调用的功能,例如C程序能调用PC机BIOS中例行程序的int86()函数等。其次,C语言具有直接对C中的int和char类型的数据的某些字节或位进行操作的能力,这与汇编语言的位操作有些相似,例如按位取反等。12.1位运算符C语言提供的位运算符如表12.1所示。表12.1位运算符位运算符含义举例&按位与A&b,a和b中各位按位进行“与”运算|按位或a|b,a和b中各位按位进行“或”运算^按位异或A^b,a和b中各位按位进行“异或”运算~取反~a,对a中各位取反<<左移A<<2,a中各位全部左移2位>>右移a>>2,a中各位全部右移2位位运算还可以与赋值运算符相结合,成为位运算赋值操作。例如,a&=b,等价于a=a&b。下面分别介绍各运算符。12.1.1按位与运算符(&)按位与运算的运算规则是:参加运算的两个运算量,如果两对应位都是1,则该位的结果为1,否则为0。例如,两个二进制数0101和1100按位与运算的结果为0100。例12.1计算8和13两个十进制数按位与运算的结果。main(){unsignedchara,b;a=8;b=13;printf(“%d&%d=%d\n”,a,b,a&b);}程序输出结果为:8&13=8说明:程序中数a即8的二进制形式为1000,数b即13的二进制形式为1101,两数按位相与的结果为1000即十进制数8。12.1.2按位或运算(|)按位或运算的运算规则是:两个相应位中只要有一个为1,该位的结果值为1,只有两个相应位都为0,该位的结果值才为0。例如,有两个十六进制数10和34,运算情况如下所示:例12.2main(){unsignedchara,b;printf(“entertwohexnumbers:”);scanf(“%x”,&a);scanf(“%x”,&b);printf(“result:”);printf(“%x|%x=%02x”,a,b,a|b);}程序运行情况如下:entertwohexnumbers:1034↙result:10|34=3412.1.3按位异或运算符(^)按位异或运算的运算规则是:参加运算的两个相应位同号,则结果为0;异号则为1。例如,有10和35两个十六进制数,运算情况如下所示:例12.3main(){unsignedchara,b;printf(“entertwohexnumbers:”);scanf(“%x”,&a);scanf(“%x”,&b);printf(“result:”);printf(“%x^%x=%02x”,a,b,a^b);}程序运行情况如下:entertwohexnumbers:1035↙result:10^35=2512.1.4取反运算符(~)取反运算的运算规则是:将一个数据中所有位都取其反值,即0变1,1变0。取反运算符(~)是一个单目运算符,运算量写在运算符之后。例如,十六进制数03(即二进制数00000011),按位取反后其值为十六进制数fc(即二进制数11111100)。12.1.5左移运算符(<<)左移运算的运算规则是:将一个数的各二进制位全部左移若干位,最左边移出的位丢失,右边空出的位补0。例如,a<<2表示将a中各位左移2位,如果a的值为十六进制数85,左移2位后的14。运算情况如下所示:当左移无溢出时,左移一位相当于乘以2,左移两位相当于乘以4。左移运算比乘法运算快得多。12.1.6右移运算符(>>)右移运算的运算规则是:将一个数的各二进制位全部右移若干位,最右边移出的位丢失,左边空出的位的补位情况分为两种:(1)对无符号的int或char类型数据来说,右移时左端补零。(2)对有符号的int或char类型数据来说,如果符号位为0(即正数),则左端也是补入0,如果符号位为1(即负数),则左端补入的全是1。对于第一种情况,由于比较简单,这里不再举例说明。对于第二种情况,举例说明如下:即十进制数-13。12.2位段C语言可以用以上介绍的位运算符访问位(bit),也可以用“位段”的方法来访问字节中的某些位。12.2.1位段的概念和定义方法位段又可称为“位字段”或“位域”,是一种特殊形式的结构体中的成员,以位为单位来定义结构体中的成员的长度。实际上它是字节中一些位的组合。下面举例说明位段的定义方法。例12.4位段定义方法举例。structdata1{unsignedinta:3;/*占3位*/unsignedintb:1;/*占1位*/unsignedintc:2;/*占2位*/unsignedintd:2;/*占2位*/}x;上面定义了结构体类型structdata1和一个该类型的变量x。该类型的数据由a、b、c和d四个(位段)成员组成,它们分别占...