240 likes | 523 Views
北京大学出版社. 《 C 语言程序设计案例教程 》. 汪新民、刘若慧主编. 主讲:傅 丰 黄淮学院信息工程学院. Huanghuai University Department of Information Engineering. 第八章 位运算. §1 位运算概念 §2 位运算符使用方法 §3 位运算应用举例. § 8.1位运算概述. 计算机真正执行的是由0和1信号组成的机器指令,数据也是以二进制表示的。因此最终实现计算机的操作,就要对这些0和1信号进行操作。每一个0和1的状态称为一个位的状态。. 按二进制位进行运算
E N D
北京大学出版社 《 C语言程序设计案例教程》 汪新民、刘若慧主编 主讲:傅 丰 黄淮学院信息工程学院 Huanghuai University Department of Information Engineering
第八章 位运算 • §1位运算概念 • §2位运算符使用方法 • §3位运算应用举例
§ 8.1位运算概述 计算机真正执行的是由0和1信号组成的机器指令,数据也是以二进制表示的。因此最终实现计算机的操作,就要对这些0和1信号进行操作。每一个0和1的状态称为一个位的状态。 • 按二进制位进行运算 • 位运算的运算对象是二进制的位 • 位运算速度快,效率高,节省存储空间 • 只能对整型数据(包括字符型)进行位运算 • 负数以补码形式参与运算 • 注意与逻辑运算区别
§ 8.2 位运算符使用方法 按位与 (Bitwise AND) • 运算规则 • 0 & 0 = 0; • 0 & 1 = 0; • 1 & 0 = 0; • 1 & 1 = 1; • 用法 保持1个数的某(些)位不变,其余各位置0。
实现方法 (1) 构造1个整数:保持不变的位为1,其余为0。 (2) 进行按位与操作。 例如,保持9的最低位不变,其余各位置0 : ● 构造1个整数00000001=1 ● 9 & 1 = 00000001。 思考:如何保留整数x的最低2位,其余各位置0 ?
按位与举例 • 运算举例 1010,1101 (0xAD) & 0110,1001 (0x69) 0010,1001 (0x29) • 按位清零、保留 xxxx,xxxx_____ & 0110,0010 (0x62) 0xx0,00x0_____
按位或 (Bitwise Inclusive OR) • 运算规则 • 0 | 0 = 0; • 0 | 1 = 1; • 1 | 0 = 1; • 1 | 1 = 1; • 用法 将1个数的某(些)位置1,其余各位不变。
实现方法 (1) 构造1个整数:置1的位上为1,其余位均为0。 (2) 进行按位或操作。 例如,将8的最低位置1 ,其余各位不变: ● 构造整数00000001=1 ● 8 | 1 = 00001001 思考:如何将整数x的最低2位置1,其余各位不变?
按位或举例 • 运算举例 1010,1101 (0xAD) | 0110,1001 (0x69) 1110,1101 (0xED) • 按位置一 xxxx,xxxx_____ | 0110,0010 (0x62) x11x,xx1x_____
按位异或 (Bitwise Exclusive OR, XOR) • 运算规则 • 0 ^ 0 = 0; • 0 ^ 1 = 1; • 1 ^ 0 = 1; • 1 ^ 1 = 0; • 说明 使1个数的某(些)位翻转,其余各位不变。 1→0,0→1
实现方法 (1)构造1个整数:要翻转的位上为1,其余均为0。 (2)进行按位异或操作。 例如,使9的最低2位翻转,其余各位不变: ● 构造整数00000011=3 ● 9 ^ 3 = 00001010。 思考:如何使整数x的最低2位翻转,其余各位不变?
按位异或用法举例 • 特定位翻转 1010,1101 (0xAD) ^ 0110,1001 (0x69) 1100,0100 (0xC4) • 与0相异或,保持原值不变 • 与自身相异或,则全部位清零 • 交换两个整数值 • a=a^b; b=b^a; a=a^b;
按位取反 (One's Complement) • 运算规则 • ~ 0 = 1; • ~ 1 = 0; • 用法 间接地构造一个全1的数( ~ 0 )。 • 获得适用于不同系统的位运算模板 无论16/32位计算机,0的表达都是0。
按位取反举例 • 运算举例 ~ 1010,1101 (0xAD) 0101,0010 (0x52) • 位运算模板 • 对一个int类型的整数最后四位清零 16位整数: a & 0xF0 32位整数: a & 0xFFF0 可以使用: a & ~(int)0xF
左移 (Left Shift) • 运算规则 • i << n • 把i各位全部向左移动n位 • 最左端的n位被移出丢弃 • 最右端的n位用0补齐 • 用法 • 若没有溢出,则左移n位相当于乘上2n • 运算速度比真正的乘法和幂运算快得多
左移举例 • 运算举例 1010,1101 << 3 (101)0110,1000_____ • 溢出举例 • 若左移后的数据超出表示范围,则发生溢出 • int i, j; i = 0x2431; j = i<<2; /* j=-0x6F3C, 溢出 */ j = i<<3; /* j= 0x2188, 溢出 */
右移 (Right Shift) • 运算规则 • i >> n • 把i各位全部向右移动n位 • 最右端的n位被移出丢弃 • 最左端的n位用0补齐(逻辑右移) • 或最左端的n位用符号位补齐(算术右移) • 用法 • 右移n位相当于除以2n,并舍去小数部分 • 运算速度比真正的除法和幂运算快得多
右移举例 • 运算举例 0101,1101 >> 3 0000,1011(101) • 逻辑右移和算术右移 • int i, j; i=-0x2431; j=i>>2; /* j=0x36F3, 逻辑右移 */ j=i>>2; /* j=0xF6F3, 算术右移 */
不同长度数据位运算规则 • 两个操作数右端对齐 • 短的数据左端用符号位补齐 • 正数或无符号数左端用0补满 • 负数左端用1补满 • 两个操作数长度相等后再运算
说明: 1. 操作数(x、y和“位数”):只能是整型(或字符型):数据。 2. 操作数x和y参与运算时,都必须首先转换成二进制,然后再执行相应的按位运算。 3. 复合赋值位运算符 除按位取反运算外,其余5个均可构成复合赋值运算符: &= |+ ^= <<= >>=。
§ 8.3位运算举应用举例 • 将16进制短整数按二进制打印输出 输入:F1E2 输出:1111000111100010 输入:13A5 输出:0001001110100101
例1:将16进制数按二进制输出 include <stdio.h> void main() { int i; short a; scanf("%X", &a); for (i=15;i>=0;i--) printf("%1d", a&1<<i?1:0); }
课后作业 P292 第2、3、4、5、6、8题 上机任务 • 调试教材P284的例9、例10。 • 调试P292作业第4、5、6、8题