C语言的按位运算

按位运算

C语言有这些按位运算的运算符

  • &   按位的与
  • |    按位的或
  • ~  按位取反
  • ^   按位的异或
  • << 左移
  • >> 右移

按位与&

  • 如果x的第i位是1且y的第i位是1,那么(x&y)的第i位是1,否则的话(x&y)的第i位是0
  • 按位与常用于两种应用:
  • 让某一位或某些位为0
  • 取一个数中的一段

按位或|

  • 如果x的第i位是1或y的第i位是1,那么(x|y)的第i位是1,否则的话(x|y)的第i位是0
  • 按位或常用于两种应用:
  • 让某一位或某些位为1
  • 把两个数拼起来

按位取反~

  • 把1位变0,0位变1
  • 想要得到全部位为1的数:~0

逻辑运算VS按位运算

  • 对于逻辑运算,它只看到两个值:0和1
  • 可以认为逻辑运算相当于把所有非0值都变成1,然后做按位运算

按位异或

  • 如果x的第i位和y的第i位相等,那么(x^y)的第i位是0,否则的话(x^y)的第i位是1
  • 如果两个位相等,那么结果为0;不相等,结果为1
  • 对一个变量用同一个值异或两次,等于什么也没做

曾经面试金山WPS的时候有一道题问到:不使用额外的空间,交换两个整形数字。

有两种方法

方法一:算术方法

x = x + y;
y = x - y;
x = x - y;

方法二:异或方法

x = x^y;// 只能对int,char..
y = x^y;
x = x^y;

移位运算:左移<<

  • i << j
  • i中所有的位向左移动j个位置,而右边填入0
  • 所有小于int的类型,移位以int的方式来做,结果是int
  • x = x<<1 等价于 x = x*2
  • x = x<<n 在范围内等价于x = x*(2的n次方)

移位运算:右移>>

  • i >> j
  • i中所有的位向右移j位
  • 所有小于int的类型,移位以int的方式来做,结果是int
  • 对于unsigned的类型,左边填入0
  • 对于signed的类型,左边填入原来的最高位
  • x = x>>1 等价于 x = x/2
  • x = x>>n 等价于 x = x/(2的n次方)

no zuo no die

  • 移位的位数不要用负数,这是没有定义的行为

利用按位与和移位操作实现输出一个数的二进制:

#include<stdio.h>

int main(int argc,int *argv[])
{
    int number;
    scanf("%d",&number);
    unsigned int mask = 1;
    mask = mask << 31;
    while(mask)
    {
        if(number & mask)
        {
            printf("1");
        }
        else
        {
            printf("0");
        }
        mask = mask>>1;
    }
    return 0;
}

 

位段

把一个int的若干位组合成一个结构

如:

struct U0
{
    unsigned int leading : 3;
    unsigned int FLAG1:1;
    unsigned int FLAG2:1;
    int trailing :27;
};

 

  • 这样就可以直接用位段的成员名称来访问,以移位、与、或更方便
  • 编译器会安排其中的位的排列,不具有可移植性
  • 当所需的位超过一个int时会采用多个int

 

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注