欢迎访问文稿网!

c语言移位运算符怎么用

范文之家 分享 时间: 加入收藏 我要投稿 点赞

c语言移位运算符怎么用

    2.4.5 位运算符和位表达式

    位运算是指进行二进制位的运算。在C语言中,位运算符有位逻辑运算符和移位运算符。为了使没有学过汇编语言的读者对二进制位运算能有较好的理解,先介绍有关位的知识以及计算机中数值的编码表示方法。

    1.字节和位

    前已讲述,内存是以字节为单位的连续的存储空间,每个内存单元(字节(byte))有一个唯一的编号,即地址。

    一个字节由8个二进制位(bit)组成,其中最右边的一位称为“最低位”,最左边的一位称为“最高位”。每一个二进制位的值是0或1。

    2.数值的编码表示

    在计算机内表示数值的时候,以最高位作为符号位,最高位为0表示数值为正,为1表示数值为负。表示数值,可采用不同的编码方法,一般有:原码、反码和补码。

    (1)原码

    用最高位作为符号位来表示数的符号:为0代表正数,为1代表负数,其余各位代表数值本身的绝对值(以二进制表示)。

    例如:

    +10的原码是:00001010

    img115

    为简化起见,假如用一个字节(八个二进位)表示整数。如果用两个字节存放一个整数,情况是一样的,只是把+10表示成00000000 00001010而已。

    +0的原码是:00000000

    −0的原码是:10000000

    显然,+0和−0表示的是同一个数0,而在内存中却有两个不同的表示。由于0的表示方法不唯一,不适合计算机的运算,所以在计算机内部一般不使用原码来表示数。

    (2)反码

    正数的反码与原码相同,如+10的反码也是00001010。

    而负数的反码是:原码除符号位外(仍为1),各位取反。如−10的反码是11110101。

    +0的反码是:00000000

    −0的反码是:11111111

    同样,0的表示不唯一。所以在计算机内部一般也不使用反码来表示数。

    (3)补码

    正数的补码与原码相同。如+10的补码同样是00001010。而负数的补码是:除最高位仍为1外,原码的其余各位求反,最后再加1。例如,−10的原码是:10001010,求反(除最高位外)后,得到11110101,再加1,结果是11110110。或者说,负数的补码是其反码加1。

    +0的补码是:00000000

    −0的补码是:11111111

    img116

    所以,用补码形式表示数值0时,是唯一的,都是00000000。

    现在计算机通常都是以补码形式存放数。因为采用补码形式不仅数值表示唯一,而且能将符号位与其他位统一处理。实际上采用补码,在计算机中可以使减法变为加法,为硬件实现提供方便。

    3.位逻辑运算符与位逻辑表达式

    位逻辑运算符有4种:

    &(按位与);∣(按位或);~(按位取反);^(按位异或)。

    由于它们都是按二进制位逐位地进行运算,相邻位之间不发生联系,即没有“进位”、“借位”等问题,所以称为位逻辑运算符。对参加逻辑运算的操作数,编译者是取其二进制的表达式进行的。

    其中,除按位取反~是单目运算符外,其余3个是双目运算符。

    位逻辑运算符的作用如表2.4.2所示。

    

    表2.4.2 位逻辑运算符的作用

    img117

    (1)“按位与”运算符(&)

    按位与的运算规则是:如果两个相应的二进制位都为1,则该位的结果为1,否则为0。即:

    1 &1= 1,1 &0= 0,0 &1= 0, 0 &0= 0

    例如:对下面的两个数进行按位与运算。

    unsigned int i=4988,j=63286;

    i为:

    0001001101111100(即0x137C或011574)

    j为:

    1111011100110110 (即0xF736或0173466)则i&j为:

    img118

    &运算经常用于把特定位清零(屏蔽)。例如i的值为10100110,j的值为11100000,则i&j的结果是10100000,相当于把i的低5位屏蔽,高3位不变。可见,若要把某数的某些二进制位取出来,可以把其他位清零,把需要取出来的位同1做按位与即可。

    注意:如果两个长度不同的数据(例如long型和int型)进行位运算时(如i&j,i为long型,j为int型),系统会将二者按右端对齐。如果j为正数,则左侧16位补满0;如果j为负数,则左侧16位补满1;如果j为无符号整型数,则左侧16位也补满0。

    (2)“按位或”运算符(|)

    按位或的运算规则是:两个相应的二进制位只要有一个为1,则该位的结果为1,否则为0。即:

    1∣1= 1, 0∣1= 1, 1∣0= 1, 0∣0= 0

    以上面的例子为例,i|j的结果为:

    img119

    按位或|运算经常用于把一个数据的某些位定值为1。例如要想使一个数m的低4位改为1,只需将m与017进行按位或即可。

    (3)“按位异或”运算符(^)

    按位异或的运算规则是:如果参与运算的两个相应的二进制位相同,则该位的结果为0,否则为1。即:

    1^1=0,0^0=0,1^0=1,0^1=1

    仍以上面的例子为例,i^j的结果为:

    按位异或^运算符能使特定位按位变反,方法是将这些特定位与1异或。例如i的值为10100110,j的值为11100000,则i^j的结果是01000110。凡是与1异或的位都变反了,而与0异或的位不变。

    (4)“按位取反”运算符(~)

    用来对一个二进制数按位取反,即将0变为1,1变为0。即:

    ~1=0,~0=1

    注意:对于按位取反(~)来说,~0x7 (即~07或~7)在16位机上就是:

    1111111111111000  (即0xFFF8或0177770)

    而在32位机上却是:

    11111111111111111111111111111000(即0xFFFFFFF8或037777777770)

    所以,在C程序中,最好采用~0x7或~07来表示7的逻辑取反,而不要采用形如

      0xFFF8、0177770或0xFFFFFFF8、037777777770

    等表达式。主要原因是:前一种表达式与机器硬件特性无关,从而保证了程序的可移植性。

    各个位逻辑运算符的优先级关系是:~最高,其余3个运算符的优先级从高到低依次是&、^、|,但三者都高于逻辑运算符而低于关系运算符。它们容易混淆,所以使用时注意加括号。例如:

      n =((i&j)|k)

    由位逻辑运算符和运算分量构成的表达式称做位逻辑表达式。位逻辑表达式中运算分量都应该是整型量或字符型量,不允许是浮点型量。

    位逻辑运算符与逻辑运算符之间的区别:

    ①位逻辑运算符是针对二进制位的,而逻辑运算符是针对整个表达式的;位逻辑运算符要计算表达式的具体数值,而逻辑运算符只判断表达式的真与假。

    ②位逻辑运算符&、|和 ^的两个运算分量是可交换的;而逻辑运算符&&和||的两个运算分量是不可交换的,并且它们严格执行自左至右的运算。例如:

      40&8 结果是8   40&&8 结果是1(真)

      40|8 结果是40  40||8 结果是1(真)

      0||x 结果是1(若x≠0) 或0(若x= 0)

      0&&x 结果是0,其中x是任意表达式

    位逻辑运算符通常用于与硬件相应的程序中,如设备驱动程序,对表示状态字中的某些位进行测试、设置和屏蔽等。

    4.移位运算符和移位表达式

    C语言中实现移位功能的运算符有两个:“〈〈”(左移)和“〉〉”(右移)。

    它们都是双目运算符,并且要求两个运算分量都是整型量。由移位运算符和运算分量构成的表达式称为移位表达式。

    (1)左移位运算符〈〈

    它的一般使用形式是:

      表达式1〈〈表达式2

    其中,“表达式1”是移位对象,“表达式2”是表示移位的位数。它的功能是:把表达式1的值(以二进制形式表示)向左移动n位,n值由表达式2确定(该值必须是正整数)。

    例如,m=00001011,那么,移位表达式

      m=m〈〈3

    的结果是01011000,即把m的各二进制位全部向左移3位,右边空出的位补0,而左边溢出的位被丢弃不管。

    在容许的范围内,利用左移位运算可扩大原数的倍数,左移1位扩大2倍,左移2位扩大4倍,即可实现被移对象乘以n2功能。例如,上面m的值是11,左移3位后,结果值是88,恰好等于11×2³ =11×8=88。

    (2)右移运算符〉〉

    它的一般使用形式是:

      表达式1〉〉表达式2

    其中,“表达式1”是移位对象,“表达式2”是表示移位的位数。它的功能是:把表达式1的值(以二进制形式表示)向右移n位,n的值由表达式2确定(该值必须是正整数)。

    例如,m=00001011,那么,移位表达式

      m= m〉〉2

    的结果是00000010,即:把m的各二进制位全都向右移2位,右边溢出的位被丢弃,而左边空出的位(在本例情况下)补0。

    右移一位相当于该数除以2,右移n位相当于该数除以n2。

    在右移时,要注意符号位问题。如果移位对象是无符号数,那么右移时左边空出来的位全以0填充,这种方式称为逻辑右移方式;如果移位对象是有符号数,当移位对象是正数(符号位为0)时,左边空位用0填充;当移位对象是负数(符号位为1)时,左边空位是补0还是补1,要取决于所用的计算机系统。有的系统按逻辑右移方式(即补0)处理,有的系统则按算术右移方式(即补1)处理。

221381
领取福利

微信扫码领取福利

微信扫码分享