C语言中的位运算

 数据移位操作在代码中如何实现

1,在实际的位运算当中,我们通常需要知道二进制、八进制、十进制、十六进制之间的转换,

这里我们以十六进制作为例子

例如;x=0x27,y=0x3f ;

0x27=0010 0111

0x3f=0011 1111

当我们需要将x进行移位操作时;看自己需要移多少位,假如我们移三位;

#include
int main(int argc, const char *argv[])
{
	unsigned char x=0x27,y=0x3f,z,f,a=5;//为无符号字符型

	z=x<<3;//将x左移三位
	f=x>>3;//将y右移三位

		printf("%#x,%#x\n",z,f);

	
	return 0;
}

看输出结果

0x38,0x4

x左移3位之后赋给z=0x38=0011 1000 ;y右移3位赋给f=0x04;这里显示0x4,在Linux系统下会自动省略0,则现在f=0x4=0000 0100 ;可以很清楚的看到进行移位之后的数据,这里过程当中有一个比较容易不清楚的地方,就是在移位过程中;

原来是0x27=0010 0111 

移位过程中 001 0011 1000 000

移位之后 0011 1000

这里要注意移位过程中前面的数移出去以后,后面补0,而不是循环到第一位,这种理解方式是错误的

如何把一个无符号数的某一位快速置 1,清 0;如何利用位预算把十进制转化为一个十六进制数,对运算取余,求整;

这里我们就要利用前面说过的移位操作;

那要如何进行置1,清0呢?在C语言当中我们利用   |(或)来置1 ,用  &(与)来清0

当我们想要某一位快速置1,可以将原数据或上0000 0001,也就是1,例如需要将y第6位置1;

将x第2位清0;代码如下;

#include
int main(int argc, const char *argv[])
{
	unsigned char x=0x27,y=0x3f,z,f,a=5;

	
	z=x&~(1<<(a-3));//将x第2位清0
	f=y|(1<<(a+1));//将x第6位置1

		printf("z=%#x,f=%#x\n",z,f);

	
	return 0;
}

这里需要注意的是,我们进行清0用的是&(与)运算,两个真才为1,一个真一个假为0,而这里我们清0的是第二位

0x27=0010 0111

1=0000 0001

1<<2表示1左移两位 0000 0100

~1<<2表示将移位之后取反 1111 1011

将得到的取反和0x27相与得到

0x27=0010 0111

取反后1111 1011

    0010 0111

& 1111 1011

    0010 0011

=0x23 

置1过程也是这样,这里留给读者自己下去尝试一遍

代码运行结果如下

z=0x23,f=0x7f

接下来就是如何利用位运算把十进制转化位十六进制;

我们都知道16=2^4

先看代码;

#include

int main(int argc, const char *argv[])
{
	int a=65,b=0;
	printf("%#x,%d,%#x,%d\n",a,a,b,b);

	b=a>>4;//将a取整

	printf("%#x,%d,%#x,%d\n",a,a,b,b);


	b=a&0xf;//将a取余

	printf("%#x,%d,%#x,%d\n",a,a,b,b);

	return 0;
}

运行结果

0x41,65,0,0
0x41,65,0x4,4
0x41,65,0x1,1

代码当中的取整和取余是怎么来呢;

a=65 转化为十六进制为0x41=0100 0001

65= 4*16+4*1

当我们将a右移4位后得到的就是取整后的数

0x04=0000 0100

大家肯定疑惑为什么右移4位就是取整后的数了呢

我们知道在数学当中65/16=4.....1

当我们计算某一个数运算除法的时候例如 %(取余)  /(取整)

在C语言中65/16=4  65%16=1

在65(十进制)转化为  0x41(十六进制) 在0x41当中 4就是取整的,1就是取余的

我们移位就是将余数1给剔除掉,计算其他数也是一样的,例如a=2665

代码如下

#include

int main(int argc, const char *argv[])
{
	int a=2665,b=0;
	printf("%#x,%d,%#x,%d\n",a,a,b,b);

	b=a>>4;

	printf("%#x,%d,%#x,%d\n",a,a,b,b);


	b=a&0xf;

	printf("%#x,%d,%#x,%d\n",a,a,b,b);

	return 0;
}

运行结果

0xa69,2665,0,0
0xa69,2665,0xa6,166
0xa69,2665,0x9,9

可以看到2665转化为十六进制为0xa69,右移4位,取整得到166,取余为9

取余过程和上面道理一样,上面是将余数给剔除掉,取余的过程就是把取整给剔除掉,

由于余数是0-15,所以在我们取余的时候只保留余数部分

例如;

0x41=0100 0001

       &0000 1111

=       0000 0001

所以得到余数1,这里要理解我们的目的是得到余数,不需要整数,取余的过程相当于将不是余数的部分清0,清0用&;

  整数部分不要&0,余数部分保留&1

以上就得到基本的位操作

你可能感兴趣的:(c语言,开发语言)