位运算符和位运算

位运算:进行而进制为的运算

系统软件常常要处理而进制的问题。
eg:将一个存储单元中的各二进制位左移或者右移一位,两个数按位相加等等。

云算符        含义
&            按位与
|            按位或
^            按位异或
~            取反
<<            左移
>>            右移

运算量只能够是整型或字符型的数据,不能够为实型数据。

1)按位与
同则不变,异则为0 ;
eg:
     011
(&)101
—————————
     001
即为:
3&5=1;

用途:
(1)清零
eg:要将一个单元清零,即使其全部而进制为0,只要找一个二进制数,其中各个位符合以下条件:原来的数中的1的位,相对应的位为0.然后使二者进行&运算,即可达到清零的目的。
eg:
        00010101
(&)     11101010
___________________
        00000000

(2)取一个数中的某些指定位。
eg:有个整数a(2个字节),想要起其中的低字节,只需要将a与(377)8 进行按位与。
(377)后面的8个位都是1,前面的高字节的位都是0,相与了之后,只保留了低字节的数据。

(3)想要保留哪一个位置的数据,就要在哪一个位置上的数进行&运算,次数在该位取1。
就是上面(2)中的一般性。

2)“按位或”运算符(|)
就是而进制为上主要有一个是“1”,结果在该位位上就是 1 的结果。
作用就是:具有保留“1”的作用。

3)“异或”运算符(^)——————————> 判断两个位置上是否为“异”,为“异”就去1,否则为0;
同则为0,异则为1.

应用:
(1)是特定的位翻转
与所有位上的数都是1 的进行异或的时候,该位上的数据将会翻转;0——>1; 1——>0 ;

(2)与0相^,保留原值。

(3)交换两个值,不用临时变量
eg:
a=3,b=4;
将a、b的值进行交换,可以实现如下:
a = a^b;
b = b^a;
a = a^b;
原理:
a = a^b;
    a= 011
(^) b= 100
————————————
    a= 111 = 7
(^) b= 100    b= b^a;
————————————
    b= 011 = 3
(^) a= 111
————————————
    a= 100 =4
可以实现了转换

4)“取反”运算符
单目运算符,用来对而进制数按位取反,即为将0变为1,1变为0.
~025是对8进制的25按位求反。 取反之后为:177752

5)左移运算符(<<)
将一个数的二进制位全部左移若干位
eg: a = a<<2; 将a的二进制数左移2位,右补0.
a = 15,二进制为:00001111,左移两位得:00111100,十进制为:60
(高位左移后,溢出将会舍弃)
左移一位相当于该数*2,2位则为4

总结:左移n位,将会是原来的数乘以2^n;

6)右移运算符(>>)
a>>2 表示将a的各二进制右移2位,移到右端的低位被舍弃,对无符号的数,高位补0;
eg:a=017时,二进制为:00001111
a>>2 为:00000011 舍弃了后面的两位。

即为:右移n位,相当于除以2^n位。(无符号的)

有符号的
正数的时候:如果原来的符号为0(该整数位正),则左边也是移入0(和上面一样);
如果符号位原来是1(即为:负数),则左边移入0还是1,这个要取决于所用的计算机系统。
有的系统移入0,有的系统移入1. 移入0的称为“逻辑右移”;移入1的称为“算术右移”

7)位运算赋值运算符
位运算符 与 赋值运算符可以组合称为符合赋值运算符,
eg:&= 、|= 、>>= ,<<= ,^=

8)不同长度的数据进行位运算
若是两个数据的长度不同(eg:long型和int型)进行位运算的时候,系统将会将二者按右端对齐。如果b为正数,则左侧16位补满0,若b为负数,做左端的应该补满1,如果b为无符号整数型,则左侧添满0。

8)位段(对内存中得信息一般是以字节为存储单位)
实际上一个存储信息不必要用一个或者多个字节,例如:"真"或“假”用0 、1 表示即可。
计算机中用于过程控制、参数检测或者数据通讯领域时,控制信息往往只是占有一个字节中的一个或几个二进制位,常常一个字节中存放多个信息。
即为:一个字节的每一个位都是可以用来存放信息位的。

如何向一个字节中的一个或几个二进制位进行赋值和改变它的值呢?
方法(1)
人为的将一个整型变量data分为几个部分。
eg:a ,b,c,d 分别占2位,6位,4位,4位。如果想将c的值变为12(假设原来是0)
(1》》将数12左移4位,是1100右边起第4~7位
(2》》将data与“12<<4”进行“按位或”运算,既可以将c的值变为12.
如果原来的值不是0,则应该先使它为0.
下面方法:data &=0177417  (左边的0表示8进制)
(0177417)8的二进制表示为:1111111100001111,即使data的第4~7位为0.
记住上面的字比较麻烦:可以使用
~(15<<4) 这个运算出来就是上面的数字了,其他的很大的数据也是可以使用这个方法来实现的。

方法(2)
c语言中“允许在一个结构体中以位为单位来指定其成员所占内存长度”,这种以位为单位的“位段”或“位域”
。利用为段可以较少的位数存储数据。
eg:
struct packed_data{
    unsigned a:2;
    unsigned b:6;
    unsigned c:4;
    unsigned d:4;
    int i;
}data;
其中a,b,c,d 分别占2位、6位、4位、4位,i位整型,共占用4个字节。

下面关于位段的定义和引用:
(1)位段成员的类型必须指定位unsigned或int类型
(2)若某一位段要从另一个字开始存放,可以一下定义:
unsigned a:1;
unsigend b:2; 一个单元存储
unsigned :0;
unsigned c:3; ;另一个单元存储

ps:本来adb是可以存放在一个存储单元中的,由于用了长度为0的位段,其作用使下一位段从下一个存储单元开始存放。
因此,现在只是将a,b存储在一个单元中,c另存放在下一个单元。

(3)一个位段必须存储在一个单元中,不可以跨越两个单元。(即为:当前的单元的空间不够用,就用下一个单元进行存储)

(4)可以定义无名位段
unsigned a:1;
unsigned  :2;(该空间是无名位段,空间不用)
unsigned b:3;
unsigned c:4;

(5)位段的长度不能够大于存储单元的长度,也不能够定义位段数组。
(6)位段可以用整型格式符输出。
eg:printf("%d,%d,%d",data.a,data.b,data.c);
当然也是可以使用%u,%0,%x等等格式来定义的。
(7)位段可以在数值表达式中引用,它会被系统自动的转换为整型数。













  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值