位运算 + c语言作业【第四次】

位运算

整数在计算机中用二进制的位来表示,C语言提供一些运算符可以直接操作整数中的位,称为位运算,这些运算符的操作数都必须是整型的。参与运算的两数各对应的二进位相运算,均以补码出现。 

& 按位与, | 按位或 , ^ 按位异或

AND (位与&) OR ( 位或| ) XOR ( 位异或^ )

1 & 1 = 1, 1 | 1 = 1, 1 ^ 1 = 0

1 & 0 = 0, 1 | 0 = 1, 1 ^ 0 = 1

0 & 1 = 0, 0 | 1 = 1, 0 ^ 1 = 1

0 & 0 = 0, 0 | 0 = 0, 0 ^ 0 = 0

位运算符

  • ~ 取反 (包括符号位!与反码相区别!)

~是一元运算符,用来对一个二进制数按位取反,即将0变1,将1变0

移位运算符(不会改变原数值的大小)

移位运算符是位操作运算符的一种,可以在二进制的基础上对数字进行平移。按照平移的方向和填充数字的规则分为三种:<<(左移)、>>(带符号右移)和>>>(无符号右移)。

左移运算是将一个二进制位的操作数按指定移动的位数向左移位,移出位被丢弃,右边的空位一律补0。右移运算是将一个二进制位的操作数按指定移动的位数向右移动,移出位被丢弃,左边移出的空位或者一律补0,或者补符号位。

在移位运算时,byte、short和char类型移位后的结果会变成int类型,对于byte、short、char和int进行移位时,编译器未做任何优化的情况下(优化后不可预期),规定实际移动 的次数是移动次数和32的余数,也就是移位33次和移位1次得到的结果相同。移动long型的数值时,规定实际移动的次数是移动次数和64的余数,也就是 移动66次和移动2次得到的结果相同。

  • 左移运算符

需要移位的数字 << 移位的次数

在数字没有溢出的前提下,对于正数和负数,左移一位都相当于乘以2的1次方,左移n位就相当于乘以2的n次方。

  • 带符号右移运算符(算数移位)

需要移位的数字 >> 移位的次数

右移一位相当于除2,右移n位相当于除以2的n次方。

  • 无符号右移运算符(逻辑移位)

按二进制形式把所有的数字向右移动对应位数,低位移出(舍弃),高位的空位补零。对于正数来说和带符号右移相同,对于负数来说不同。

例.请编写一个c函数,该函数给出一个字节中被置为1的位的个数

 解决该题的四种方法(方法三还没懂?)

while (v)
{
v &=(v-1);         //v=v&(v-1)这个操作可以直接消除掉v中的最右边的1。
num++;            //最后num即为1的个数
}

 

例.输入一个整数a,再输入两个整数p1,p2(p1,p2<32),将该整数的二进制表示方法中从右端开始的p1到p2位取反后输出

第31行要取反,应该用~取反,再与1位与。如果先与1位与,再取反,0取反结果是-1,1取反结果是-2,因为符号~包括符号位它也会取反。

 

例.输入一个32位的整数a,使用按位异或^运算,生成一个新的32位整数b,使得该整数b的每一位等于原整数a中该位左右两边两个bit位的异或结果(提示:0 ^ 0 = 0; 1 ^ 1 = 0; 0 ^ 1 = 1; 1 ^ 0 = 1)

该题首位和末尾我自己做了个特殊处理

 之前想的时候是想同过每位乘上2的n次方把b算出来。但通过位运算可以比较简便的处理这个问题。

例.从键盘上输入1个正整数给int变量num,按二进制位输出该数。

该题解法的亮点是如何正序输出

#include  "stdio.h"
main()
    { int num, mask, i;
       printf("Input a integer number: ");
       scanf("%d",&num);
       mask = 1<<31;  
                   /*构造1个最高位为1、其余各位为0的整数(屏蔽字)*/
      printf("%d=" , num);
      for(i=1; i<=32; i++)
         { putchar(num&mask ? ’1’ : ‘0’);	//取巧,为0是是不成立,非零是成立(就不一定要结果是1才成立了)
                /*输出最高位的值(1/0)*/
            num <<= 1;  			
                /*将次高位移到最高位上*/
            if( i%4==0 ) putchar(‘,’); 
               /*四位一组,用逗号分开*/
        }
      printf("\bB\n");
    }

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值