24
C 语语语语语语语语语语Huanghuai University Department of Information Engineering 语语 语语语语语语语语语语 北北北北北北北 北北北 北北北北北

《 C 语言程序设计案例教程 》

  • Upload
    beulah

  • View
    157

  • Download
    1

Embed Size (px)

DESCRIPTION

北京大学出版社. 《 C 语言程序设计案例教程 》. 汪新民、刘若慧主编. 主讲:傅 丰 黄淮学院信息工程学院. Huanghuai University Department of Information Engineering. 第八章 位运算. §1 位运算概念 §2 位运算符使用方法 §3 位运算应用举例. § 8.1位运算概述. 计算机真正执行的是由0和1信号组成的机器指令,数据也是以二进制表示的。因此最终实现计算机的操作,就要对这些0和1信号进行操作。每一个0和1的状态称为一个位的状态。. 按二进制位进行运算 - PowerPoint PPT Presentation

Citation preview

Page 1: 《 C 语言程序设计案例教程 》

《 C 语言程序设计案例教程》

Huanghuai University Department of Information

Engineering

主讲:傅 丰黄淮学院信息工程学院

北京大学出版社

汪新民、刘若慧主编

Page 2: 《 C 语言程序设计案例教程 》

第八章 位运算• §1 位运算概念• §2 位运算符使用方法• §3 位运算应用举例

Page 3: 《 C 语言程序设计案例教程 》

§ 8.1 位运算概述

• 按二进制位进行运算• 位运算的运算对象是二进制的位• 位运算速度快,效率高,节省存储空间• 只能对整型数据 ( 包括字符型 ) 进行位运算• 负数以补码形式参与运算• 注意与逻辑运算区别

计算机真正执行的是由 0 和 1 信号组成的机器指令,数据也是以二进制表示的。因此最终实现计算机的操作,就要对这些 0 和 1 信号进行操作。每一个 0 和 1 的状态称为一个位的状态。

Page 4: 《 C 语言程序设计案例教程 》

位运算符 (Bitwise Operators)

运算符 名称 举例 优先级~ 按位取反 ~flag ( 高 )

( 算术运算符 )

<< 左移 a << 2

>> 右移 b >> 3

( 关系运算符 )

& 按位与 flag & 0x37

^ 按位异或 flag ^ 0xC4

| 按位或 flag | 0x5A ( 低 )

( 赋值运算符 )

Page 5: 《 C 语言程序设计案例教程 》

按位与 (Bitwise AND)• 运算规则

– 0 & 0 = 0;– 0 & 1 = 0;– 1 & 0 = 0;– 1 & 1 = 1;

• 用法

保持 1 个数的某 (些 )位不变,其余各位置 0 。

§ 8.2 位运算符使用方法

Page 6: 《 C 语言程序设计案例教程 》

实现方法(1) 构造 1 个整数:保持不变的位为 1 ,其余为 0 。(2) 进行按位与操作。例如,保持 9 的最低位不变,其余各位置 0 :● 构造 1 个整数 00000001=1

● 9 & 1 = 00000001 。思考:如何保留整数 x 的最低 2位,其余各位置 0

Page 7: 《 C 语言程序设计案例教程 》

按位与举例

• 运算举例 1010,1101 (0xAD)

& 0110,1001 (0x69)

0010,1001 (0x29)• 按位清零、保留

xxxx,xxxx_____

& 0110,0010 (0x62)

0xx0,00x0_____

Page 8: 《 C 语言程序设计案例教程 》

按位或 (Bitwise Inclusive OR)

• 运算规则– 0 | 0 = 0;– 0 | 1 = 1;– 1 | 0 = 1;– 1 | 1 = 1;

• 用法 将 1 个数的某 ( 些 ) 位置 1 ,其余各位不变。

Page 9: 《 C 语言程序设计案例教程 》

实现方法(1) 构造 1 个整数:置 1 的位上为 1 ,其余位均为

0 。(2) 进行按位或操作。例如,将 8 的最低位置 1 ,其余各位不变:● 构造整数 00000001=1

● 8 | 1 = 00001001

思考:如何将整数 x 的最低 2位置 1 ,其余各位不变?

Page 10: 《 C 语言程序设计案例教程 》

按位或举例

• 运算举例 1010,1101 (0xAD)

| 0110,1001 (0x69)

1110,1101 (0xED)• 按位置一

xxxx,xxxx_____

| 0110,0010 (0x62)

x11x,xx1x_____

Page 11: 《 C 语言程序设计案例教程 》

按位异或 (Bitwise Exclusive OR, XOR)

• 运算规则– 0 ^ 0 = 0;– 0 ^ 1 = 1;– 1 ^ 0 = 1;– 1 ^ 1 = 0;

• 说明

使 1 个数的某 ( 些 ) 位翻转,其余各位不变。

1→0 , 0→1

Page 12: 《 C 语言程序设计案例教程 》

实现方法(1) 构造 1 个整数:要翻转的位上为 1 ,其余均为

0 。(2) 进行按位异或操作。例如,使 9 的最低 2 位翻转,其余各位不变:● 构造整数 00000011=3

● 9 ^ 3 = 00001010 。思考:如何使整数 x 的最低 2位翻转,其余各位

不变?

Page 13: 《 C 语言程序设计案例教程 》

按位异或用法举例

• 特定位翻转 1010,1101 (0xAD)

^ 0110,1001 (0x69)

1100,0100 (0xC4)• 与 0 相异或,保持原值不变• 与自身相异或,则全部位清零• 交换两个整数值

– a=a^b; b=b^a; a=a^b;

Page 14: 《 C 语言程序设计案例教程 》

按位取反 (One's Complement)

• 运算规则– ~ 0 = 1;– ~ 1 = 0;

• 用法

间接地构造一个全 1的数 ( ~ 0 ) 。– 获得适用于不同系统的位运算模板

无论 16/32 位计算机, 0 的表达都是0 。

Page 15: 《 C 语言程序设计案例教程 》

按位取反举例

• 运算举例~ 1010,1101 (0xAD)

0101,0010 (0x52)• 位运算模板

– 对一个 int 类型的整数最后四位清零16 位整数: a & 0xF0

32 位整数: a & 0xFFF0

可以使用: a & ~(int)0xF

Page 16: 《 C 语言程序设计案例教程 》

左移 (Left Shift)

• 运算规则– i << n– 把 i 各位全部向左移动 n 位– 最左端的 n 位被移出丢弃– 最右端的 n 位用 0 补齐

• 用法– 若没有溢出,则左移 n 位相当于乘上 2n

– 运算速度比真正的乘法和幂运算快得多

Page 17: 《 C 语言程序设计案例教程 》

左移举例

• 运算举例 1010,1101 << 3

(101)0110,1000_____• 溢出举例

– 若左移后的数据超出表示范围,则发生溢出– int i, j;

i = 0x2431;

j = i<<2; /* j=-0x6F3C, 溢出 */j = i<<3; /* j= 0x2188, 溢出 */

Page 18: 《 C 语言程序设计案例教程 》

右移 (Right Shift)

• 运算规则– i >> n– 把 i 各位全部向右移动 n 位– 最右端的 n 位被移出丢弃– 最左端的 n 位用 0 补齐 ( 逻辑右移 )

– 或最左端的 n 位用符号位补齐 ( 算术右移 )

• 用法– 右移 n 位相当于除以 2n,并舍去小数部分– 运算速度比真正的除法和幂运算快得多

Page 19: 《 C 语言程序设计案例教程 》

右移举例

• 运算举例0101,1101 >> 3

0000,1011(101)• 逻辑右移和算术右移

– int i, j;

i=-0x2431;

j=i>>2; /* j=0x36F3, 逻辑右移 */j=i>>2; /* j=0xF6F3, 算术右移 */

Page 20: 《 C 语言程序设计案例教程 》

不同长度数据位运算规则

• 两个操作数右端对齐• 短的数据左端用符号位补齐• 正数或无符号数左端用 0 补满• 负数左端用 1 补满• 两个操作数长度相等后再运算

Page 21: 《 C 语言程序设计案例教程 》

说明:1. 操作数 (x、 y 和“位数” ) :只能是整型

( 或字符型 ) :数据。

2. 操作数 x 和 y 参与运算时,都必须首先转换成二进制,然后再执行相应的按位运算。

3. 复合赋值位运算符

除按位取反运算外,其余 5 个均可构成复合赋值运算符: &= |+ ^= <<= >>= 。

Page 22: 《 C 语言程序设计案例教程 》

§ 8.3 位运算举应用举例

• 将 16 进制短整数按二进制打印输出

输入: F1E2

输出: 1111000111100010

输入: 13A5

输出: 0001001110100101

Page 23: 《 C 语言程序设计案例教程 》

例 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);

}

Page 24: 《 C 语言程序设计案例教程 》

课后作业

P292 第 2 、 3 、 4 、 5 、 6 、 8 题

上机任务 调试教材 P284 的例 9 、例 10 。 调试 P292 作业第 4 、 5 、 6 、 8 题