文档介绍:第11章位运算
《C语言程序设计》
课程讲义
2006年4月
上一章节课程回顾
关系运算符、逻辑运算符及其表达式
关系运算符及逻辑运算符的优先次序
逻辑运算的值
if语句的三种形式
if语句的嵌套
条件运算符和条件表达式
switch语句
第11章位运算
位域(位段)
概述
位运算符六种位运算符
C语言是为描述系统而设计的,因此它应当具有汇编语言所能完成的一些功能。第九章介绍的指针运算和本章将介绍的位运算就很适合于编写系统软件的需要。
所谓位运算是指进行二进制位的运算。在系统软件中,常要处理二进位的问题。例如,将一个存储单元中的各二进位左移或右移一位,两个数按位相加等。c语言提供位运算的功能,
为了使没有学过汇编语言的读者对二进制运算能有较好的理解,先介绍有关位的知识。
概述
一、字节和位
大多数计算机系统(包含IBM-PC系列)的内存储器是由许许多多被称为“字节”(byte)的单元组成的。
每一个字节有一个地址。一个字节由若干个二进制位(bit)组成。若干个字节组成一个存储单元,称为“字”(word)。每一个存储单元存放一个数据或一条指令。
一个字节一般由8个二进位组成,其中最右边的一位称为“最低有效位”或“最低位”,最左面的一位称为“最高有效位”或“最高位”,每一个二进位的值是0或1。
在微型机中一般以4个字节存放一个实数,以2个字节存放一个整数。最左边的一位(最高位)用作数的符号位。
为了表示数值,可以采用不同的方法,一般有:原码、反码和补码。
二、原码
只将最高位作符号位(以0代表正,1代表负),其余各位代表数值本身的绝对值(以二进制表示)。如:
概述
+7的原码为: 00000111
|
代表'正'
一7的原码为: 10000 1 1 1
|
代表,'负'
二进制的111代表十进制的7,为简化起见,我们只用一个字节存放一个整数,如果用两个
字节存放一个整数,情况是一样的,无非把+7表示成00000000 00000111而已。
十0的原码为 00000000
一0的原码为 10000000
显然,+0和一0表示的是同一个数0,而在内存中却有两个不同的表示。也就是说,0的表示
不唯一,这不适合于计算机的运算。
概述
三、反码
一个数如果值为正,则它的反码与原码相同,如:+7的反码为00000111。
一个数的值如为负,则符号位为1,其余各位是对原码取反。如:
一7的反码为:11111000
十0的反码为:00000000
一0的反码为:11111111
同样,o的表示不唯一。用反码表示的最大值为127,最小值为-127。
127的反码为: 01111111
一127的反码为: 10000000
用反码表示数,现已不多用。
四、补码
原码和反码都不便于计算机内的运算,因为在运算中要单独处理其符号。
概述
例如,对以原码表示的+7和一7相加,必须先判断各自的符号位,然后对后7位进行相应的处理,很不方便。
因此,最好能做到将符号位和其它位统一处理。对减法也按加法来处理。这就是“补码”。
“补码”的原理可以用时钟来说明,。如果要将时针从9点拨到4点,可以向前拨,也可以向后拨,其表示如下:
12
11 1
10 2
9 ------- 3
8 4
7 5
6
概述
9一5=4 (向后拨5个字)
9+7=16(向前拨7个字)
从图上可见,向前拨7个字也能指向4。这是由于钟是圆的,12点的下一个小时是1点。时钟是12进制的,可以把12点看成0点,13点就是1点,其实是进位后得到了十二进制数11,其中第一个1是进位,即高位,第二个1是低位。高位不保留,只保留低位,因此,16点用十二进制数表示为14,高位不保留,在时钟上就是4点,用十进制数可表示为:16一12=4。
对十进制数,如果想从9得到结果值5,可以用减法:
9一4=5
已知4的补数为10一4=6,即4与6互补。因此9一4可以改写为加法:
9+6 =15
概述
再去掉高位1,得5。
在计算机中,以一个有限长度的二进位作为数的模,如果用1个字节表示一个数,一个字节为8位,模为256。因为逢256就进1,在内存中情况为
------------
1|00000000|
-------------
进位被丢弃。
补码是这样规定的:
正数:其原码、反码、补码相同。例如,+7的补码也是00000111。
负数:最高位为1,其余各位为原码的相应位取反,然后对整个数加1。例如:
一7的原码: 10000111
一7的补码:第①步: 11111