C高级编程day03 位运算

一、位逻辑运算符

  4个位运算符用于整型数据,包括char.将这些位运算符成为位运算的原因是它们对每位进行操作,而不影响左右两侧的位。请不要将这些运算符与常规的逻辑运算符(&& 、||和!)相混淆,常规的位的逻辑运算符对整个值进行操作。

1.按位取反:~

  (1)一元运算符 ~ 将每个1变为0,将每个0变为1,如下面的例子:

~(10011010)
  01100101

  (2)请注意该运算符不会改变a的值,a仍为2。假设a是一个unsigned char,已赋值为2.在二进制中,2是00000010.于是~a的值为11111101或者253。

unsigned char a = 2;   //00000010
unsigned char b = ~a;  //11111101
printf("ret = %d\n", a); //ret = 2
printf("ret = %d\n", b); //ret = 253

2.位与(AND): &

  (1)二进制运算符&通过对两个操作数逐位进行比较产生一个新值。对于每个位,只有两个操作数的对应位都是1时结果才为1。这里有个技巧就是判断是一个数是否为奇数,让那个数与1相与,如果结果为1,那么就是奇数。

   (10010011) 
 & (00111101) 
 = (00010001)

  (2)在C语言中也有一个组合的位与-赋值运算符:&=。下面两个将产生相同的结果:

val &= 0377
val = val & 0377

3.位或(OR): |

  (1)二进制运算符|通过对两个操作数逐位进行比较产生一个新值。对于每个位,如果其中任意操作数中对应的位为1,那么结果位就为1. 我们可以利用或操作,将数字中指定的位置变为1.

	(10010011)
  | (00111101)
  = (10111111)

  (2)C也有组合位或-赋值运算符: |=

val |= 0377
val = val | 0377

4.位异或:^

  (1)二进制运算符^对两个操作数逐位进行比较。对于每个位,如果操作数中的对应位有一个是1(但不是都是1),那么结果是1.如果都是0或者都是1,则结果位0. 或者可以理解为无进位相加,就是和普通的加法一样,但当产生进位时要忽略

	(10010011)
  ^ (00111101)
  = (10101110)

  (2)C也有一个组合的位异或-赋值运算符: ^=

val ^= 0377
val = val ^ 0377

二、位运算符的用法

1.使用或运算符 | ,将某个为置为1

  使用或运算符 | ,将某个为置为1,这种用法也叫做打开位,就是将某个位置为1。

  已知:10011010:

  将位2打开,也就是要将这个数从右往左并且从0开始数第2个位置上面的数置为1。

 (10011010)
|(00000100)
=(10011110)

2.将所有位打开

flag | ~flag
 (10011010)
|(01100101)
=(11111111)

3.关闭位

 flag & ~flag
 (10011010)
&(01100101)
=(00000000)

4.转置位

   转置(toggling)一个位表示如果该位打开,则关闭该位;如果该位关闭,则打开。您可以使用位异或运算符来转置。其思想是如果b是一个位(1或0),那么如果b为1则b ^ 1为0,如果b为0,则1 ^ b为1。无论b的值是0还是1,0^b为b.

flag ^ 0xff

 (10010011)
^(11111111)
=(01101100)

5.用于两个数的交换

//a ^ b = temp;
//a ^ temp = b;
//b ^ temp = a
 (10010011)
^(00100110)
=(10110101)

 (10110101)
^(00100110)
  10010011
  
  int a = 10;
  int b = 30;

三、移位运算符

  现在让我们了解一下C的移位运算符。移位运算符将位向左或向右移动。同样,我们仍将明确地使用二进制形式来说明该机制的工作原理。

1.左移 <<

  (1)左移运算符<<将其左侧操作数的值的每位向左移动,移动的位数由其右侧操作数指定。空出来的位用0填充,并且丢弃移出左侧操作数末端的位。在下面例子中,每位向左移动两个位置。

(10001010) << 2
(00101000)

  (2)该操作将产生一个新位置,但是不改变其操作数。

1 << 1 = 2;
2 << 1 = 4;
4 << 1 = 8;
8 << 2 = 32

  左移一位相当于原值*2. 左移x位代表乘以 2^x 次方

2.右移 >>

  右移运算符>>将其左侧的操作数的值每位向右移动,移动的位数由其右侧的操作数指定。丢弃移出左侧操作数有段的位。对于unsigned类型,使用0填充左端空出的位。对于有符号类型,结果依赖于机器。空出的位可能用0填充,或者使用符号(最左端)位的副本填充。

//有符号值
(10001010) >> 2
(00100010)     //在某些系统上的结果值

(10001010) >> 2
(11100010)     //在另一些系统上的结果

//无符号值
(10001010) >> 2
(00100010)    //所有系统上的结果值

3. 用法:移位运算符

  移位运算符能够提供快捷、高效(依赖于硬件)对2的幂的乘法和除法。

  number << n number乘以2的n次幂

  number >> n 如果number非负,则用number除以2的n次幂

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值