C语言程序设计课件:位运算
合集下载
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
❖
补码:1 1 1 0 1 1 0 0
❖
求反:1 0 0 1 0 0 1 1
❖ +1
❖
原码:1 0 0 1 0 1 0 0
❖ 求得:[X]原=1 0 0 1 0 1 0 0B。
❖ 例:求18-15的值。 ❖ 利用补码,减法运算就转化为加法实现,变成了求[18-15 ]补,
[18-15 ]补等价为[18]补+[-15]补,先求-15 的补码,-15的二 进制表示为10001111,则-15 的补码为
❖ 反码表示规则:正数的反码与原码相同;负数的反码,符号位为 “1”不变,数值部分按位取反,即0变为1,1变为0。反码很少 直接用于计算机中,它是用于求补码的过程产物。
❖ 例如:00111000的反码为00111000,10111000的反码为11000111。 ❖ 补码的表示规则:正数的补码与原码相同;负数的补码是在反码
11.2.2位复合赋值运算符
C 语言提供了如表 11.2 所示的 5 种位复合赋值运算符。
表 11.2 位复合赋值运算符
运算符 含义
结合性
优先级(附录中等级)
&=
先对右值按位与,再赋值 自右向左
15
|=
先对右值按位或,再赋值 自右向左
15
^=
先对右值按位异或,再赋值 自右向左
15
<<=
先对右值左移,再赋值
00001101赋值给n,p的值二进制数为00000000 00000111,n&p的值对应二进制数为00000000 00000101赋值给变量t。
11.4错误解析
❖ 1.位运算要求操作数的数据类型为整型。 ❖ 2.左移运算将一个位串信息向左移指定的位,左端移出的位的
信息就被丢弃,右端空出的位用0补充。例如014<<2,结果为060, 即48。 ❖ 3.右移运算将一个位串信息向右移指定的位,右端移出的位的 信息被丢弃。例如12>>2,结果为3。与左移相反,对于小整数, 每右移1位,相当于除以2。在右移时,需要注意符号位问题。对 无符号数据,右移时,左端空出的位用0补充。对于带符号的数 据,如果移位前符号位为0(正数),则左端也是用0补充;如果移 位前符号位为1(负数),则左端用0或用1补充,取决于计算机系 统。对于负数右移,称用0 补充的系统为“逻辑右移”,用1补 充的系统为“算术右移”。
❖ 下面对各种位运算符的运算规则及其应用作以介绍。
❖ 1.按位“与”运算符“&” ❖ 运算规则:参与运算的两个数各对应的二进制位相“与”,也就
是说只有对应的两个二进制位均为1时,结果位才为1,否则为0。 即:0&0=0,0&1=0, 1&0=0,l&1=1。
❖ 按位与的应用: ❖ (1)获取一个二进制数指定位的值。 ❖ (2)定位清零。 ❖ 2.按位“或”运算符“|” ❖ 运算规则:参与运算的两个数对应的二进制位相“或”,也就是
说0变成1,1变成0。即:~0=1,~1=0。
❖ 按位取反的应用: ❖ 适当的使用可增加程序的移植性。 ❖ 5.“左移”运算符“<<” ❖ 运算规则:将“<<”与算符左边的运算数的二进制位全部左移若
干位,高位左移溢出部分丢弃,低位补0。
❖ 左移运算的应用: ❖ 当不超出数值的值域时,可以通过左移实现一个数据与2的n次方
❖ 一个英文的字符占用一个字节,而一个汉字以及汉字的标点符号、 字符都占用两个字节。一个二进制数字序列,在计算机中作为一 个数字单元,一般为8位二进制数,如一个ASCII码就是一个字节。 字节单位还有KB、MB、GB、TB等,此类单位的换算为:
❖ 1KB =1024B ❖ 1MB =1024KB ❖ 1GB=1024MB ❖ 1TB=1024GB
自右向左
15
>>=
先对右值右移,再赋值
自右向左
15
说明: (1)运算符为双目运算符。 (2)右值只能是整型或字符型的数据,不能为实型、结构体等类型的数据。 (3)左侧运算数必须是左值。 运算规则:位复合赋值运算符先对右值进行相应的位运算,然后再将运算结 果赋值给与算符左侧的变量。
11.3应用程序举例
程如下:
❖
原码:1 0 1 1 0 1 1 0
❖
反码:1 1 0 0 1 0 0 1
❖ +1
❖Hale Waihona Puke 补码:1 1 0 0 1 0 1 0
❖ 求得:[X]反=11001011B, [X]补=11001010B。
❖ 例:已知某数X的补码11101100B,试求其原码。
❖ 由[X]补=11101110B知,符号位为“1”,X为负数。补码的补码就是原码, 故求其原码表示时,符号位不变,数值部分按位求反,再在末位加1。
11.2二进制位运算
❖ 程序中的所有数据在计算机内存中都是以二进制的形式储存的。 在C语言中,位运算就是指直接对整数或字符型数据在内存中的 二进制位进行操作。很多系统程序中常要求在位(bit)一级进 行运算或处理,C语言提供了按位运算的功能,使其具有很强的 优越性,也能像汇编语言一样用来编写系统程序。
❖ ex1110输入一个数m,输出其所对应二进制数的从右端开始的第6至8位。 ❖ 分析: ❖ 首先先使m右移5位,使要取出的那几位移到最右端,再设置一个数n低3位全为1,其余的位全为0
的数,即将一个全1的数左移3位,这样右端低3位为0,最后将m&n,将m的低3位取出。程序如下: ❖ #include "stdio.h" ❖ main() ❖{ ❖ int m,n,p,t; ❖ printf("Please input m de zhi:"); ❖ scanf("%d",&m); ❖ n=m>>5; ❖ p=~(~0<<3); ❖ t=n&p; ❖ printf("m=%d,t=%d\n",m,t); ❖} ❖ 程序运行:输入416↙ ❖ 在输出结果屏上显示: ❖ m=416,t=5 ❖ 说明: ❖ 输入416,m的值为416,对应的二进制数为00000001 10100000,m左移5位后为00000000
11.1.2 补码
❖ 一个数据在计算机内部表示成二进制形式称为机器数。机器数有 不同的表示方法,常用的有原码、反码、补码。数据的最右边一 位是 “最低位”,数据最左边一位叫做 “最高位”。
❖ 原码表示规则:用最高位表示符号位,用“0”表示正号,“1” 表示负号,其余各位表示数值大小。
❖ 例如:假设某个机器数的位数为8,则56的原码是00111000,-56 的原码是10111000。
❖ 在实际应用中,注意原码、反码、补码之间的相互转换,由于正 数的原码、补码、反码表示方法均相同,当遇到正数时不需转换。 进行转换时,首先判断其符号位,为负时,再进行转换。
❖ 例:已知某数X的原码为10110110B,求X的补码和反码。
❖ 由[X]原=10110110B知,符号位为“1”,X为负数。求其反码时,符号位 不变,数值部分按位求反,求其补码时,再在其反码的末位加1。计算过
14
15
C 运算符的优先级与结合性
运算符 () [] -> . ! ~
++ -* &
(类型标识符) sizeof
*/%
+-
<< >>
< <= > >=
= = !=
& ^
|
&&
||
?:
= += -= *= /= %= &= ^= |= <<= >>=
,
含义 圆括号、函数参数表 数组元素下标 指向结构体成员 引用结构体成员 逻辑非 按位取反 增 1、减 1 求负 间接寻址运算符 取地址运算符 强制类型转换运算符 计算字节数运算符
位运算
本章要点
❖ 位运算的相关概念 ❖ 位运算符的含义及使用; ❖ 位运算的特殊应用; ❖ 位复合赋值运算符的含义及使用;
11.1位运算的概念
❖ 程序中的所有数在计算机内存中都是以二进制的形式储存的。位 运算说穿了,就是直接对整数在内存中的二进制位进行操作。由 于位运算直接对内存数据进行操作,不需要转成十进制,因此处 理速度非常快。
的基础上加二进制“1”。 ❖ 例如:00111000的补码为00111000,10111000的补码为11001000。
❖ 补码是计算机中一种重要的编码形式,采用补码后,可以将减法 运算转化成加法运算,运算过程得到简化。正数的补码即是它所 表示的数的真值,而负数的补码的数值部份却不是它所表示的数 的真值。采用补码进行运算,所得结果仍为补码。一个数补码的 补码就是它的原码。与原码、反码不同,数值0的补码只有一个, 即 [0]补=00000000B。若字长为8位,则补码所表示的范围为128~+127;进行补码运算时,所得结果不应超过补码所能表示 数的范围。
❖ 11110000 ❖ +1 ❖ 11110001 ❖ 与18 的补码相加 ❖ 00010010 [18]补 ❖ + 11110001 [-15]补 ❖ 1 00000011 [18]补+[-15]补 ❖ 舍去运算溢出的最高一位(模运算),结果为00000011,符号位
为“0”,故为正数,正数的补码为其本身,转化为十进制为3。
相乘的操作。
❖ 6.“右移”运算符“>>”
❖ 运算规则:将“>>”与算符左边的运算数的二进制位全部右移若 干位,低位右移部分丢弃。对于无符号数高位补0;对于有符号 数,如果原来符号位为0(正数),则高位补0,如果符号位为1 (负数),则高位补0或1由计算机系统决定。
❖ 右移运算的应用:
❖ 右移一位相当于该数除以2;右移n位相当于该数除以2的n次方。
❖ 按位异或的应用:
❖ (1)定位翻转,也就是说使指定位的值发生变化,1变成0,0变 成1。
❖ (2)不用临时变量,交换两个值。
❖ (3)定位保留原值,也就是说保留指定位的值,使其不发生变 化。利用保留原值位为0的二进制数与其进行“异或”运算,此 位值不会发生变化。
❖ 4.按位“取反”运算符“~” ❖ 运算规则:参与运算的一个数的各二进位按位取“反”,也就是
结合方向
自左向右
自右向左
自左向右 自左向右 自左向右 自左向右 自左向右 自左向右 自左向右 自左向右 自左向右 自左向右 自右向左
自右向左
自左向右
❖ 说明: ❖ (1)除“~”为单目运算符,其它为双目运算符。
❖ (2)运算数只能是整型或字符型的数据,不能为实型、结构体 等类型的数据
❖ (3)两个不同长度的运算数进行位运算时,系统会将两个数按 右端对齐,再将位数短的一个运算数往高位扩充,即:无符号数 和正整数左侧用0补全;负数左侧用1补全。
乘、除、整数求余
加、减 左移、右移
小于、小于等于 大于、大于等于
等于、不等于
按位与 按位异或
按位或
逻辑与
逻辑或
条件运算符
赋值运算符
复合的赋值运算符
逗号运算符
运算类型
单目运算
双目算术运算 双目算术运算
位运算 关系运算 关系运算
位运算 位运算 位运算 逻辑运算 逻辑运算 三目运算 双目运算 顺序求值运算
说只有对应的两个二进制位均为0时,结果位才为0,否则为1。 即:0|0=0,0|1=1,1|0=l, 1|1=1。
❖ 按位或的应用: ❖ 利用按位或运算将一个数据指定位值为1。
❖ 3.按位“异或”运算符“^”
❖ 运算规则:参与运算的两个数对应的二进制位相“异或”,也即 是说当二进制位相异时,结果为1,否则为0。即:0^0=0,0^1=1, 1^0=l, 1^1=0。
11.2.1二进制位运算
C 语言提供了如表 11.1 所示的 6 种位运算符。
运算符 & | ^ ~ << >>
含义 按位与 按位或 按位异或 取反 左移 右移
表 11.1 位运算符
结合性
优先级(附录中等级)
自左向右
8
自左向右
10
自左向右
9
自左向右
2
自左向右
5
自左向右
5
优先级
1
2
3 4 5 6 7 8 9 10 11 12 13
❖ 如果计算机的字长为n位,n位二进制数的最高位为符号位,其余 n-1位为数值位,采用补码表示法时,可表示的数X的范围是 2n-1≤X≤2n-1-1,如当n=8时,可表示的有符号数的范围为128~+127。两个有符号数进行加法运算时,当运算结果超出可 表示的有符号数的范围时,就会发生溢出,使计算结果出错。很 显然,溢出只能出现在两个同符号数相加或两个异符号数相减的 情况下。在计算机中,数据是以补码的形式存储的,所以补码在 c语言的学习中有比较重要的地位,而学习补码必然涉及到原码、 反码。
❖ C语言提供了位运算的功能,这使得C语言也能像汇编语言一样 用来编写系统程序。参与运算的数以补码方式出现。参与位运算 的只能是整型或字符型数据。
11.1.1 字节与位
❖ 二进制数系统中,位,简记为b,也称为比特,每个0或1就是一个 位(bit),位是数据存储的最小单位。字节(Byte)是计算机信息 存储的最小单位,1个字节等于8位二进制。计算机中的CPU位数 指的是CPU一次能处理的最大位数。例如32位计算机的CPU一个机 器周期内可以处理32位数据0xFFFFFFFF