C语言一一按位运算符

前言
C语言提供常见的运算符有算术运算符、关系运算符、逻辑运算符、位运算符、赋值运算符等。这些运算符是一种告诉编译器执行特定的数学或逻辑操作的符号。下面主要以按位运算符为例。

按位逻辑运算符
4个按位逻辑运算符都用于整形数据,包括char。之所以叫作按位运算符,是因为这些操作都是针对每一个位进行,不影响在左右两边的位。不要把这些运算符与常规运算符(&&、||和!)混淆,常规操作运算符操作是整个值。

按位取反( ~ )

一元运算符把1变为0,把0变为1。如下例子所示:

~(10011010)//表达式
 (01100101)//结果值

按位与( & )
二元运算符&通过逐位比较两个运算符对象,生成一个新值。对于每个位,只有两个运算符对象中相应的位都为1时,结果才为1 。因此对下面表达式求值:

(10010011) & (00111101) //表达式

  10010011
& 00111101
一一一一一一一
  00010001  //结果值

C语言有一个按位与和赋值结合的运算符:&= 下面两条语句产生最终的结果相同。

val &= 037;
val = val & 037;

按位或 ( | )

二元运算符 | ,通过逐位比较两个运算对象,生成一个新值。对于每个位,如果运算对象中对应的位1,结果为1。因此,对下面 的表达式求值:

(10010011) | (00111101) //表达式
(10111111) //结果值

C语言有一个按位或和赋值结合的运算符:|= 下面两条语句产生最终的结果相同。

val |= 037;
val = val | 037;

按位异或 ( ^ )
二元运算符^逐位比较两个运算对象。对于每个位,如果两个运算对象中相应的位一个为1,结果为1 。因此下面表达式求值:

   (10010011) ^ (00111101)//表达式
  
   10010011
^  00111101
一一一一一一一一一
   10101110    //结果值
 

用法:掩码
按位与运算符常用与掩码。所谓的掩码指的是一些设置为开(1)或关(0)的位组合。假设要定义符合常量 MASK 为2 (二进制表示 00000010),只有1号位是1,其他位为0。下面的语句:

flag = flag & MASK;

把flag中除1号的位以外的所有位都设置为0,因此使用按位与运算符(&)任何位0组合都得0。1号位的值不变。这个过程叫做使用掩码。

用法:打开位(设置位)
有时候需要打开一个值中的位,同时保持其他位不变。例如,为了打开电脑内置扬声器,必须打开1号位,同时保持其他位不变。这个过程情况可以使用按位或运算符 ( | )。以上面掩码用法为例。下面的语句

flag = flag | MASK;

把flag的1号位设置为1,且其他位不变。因此使用 | 运算符,任何位与0组合,结果为本身;任何位与1组合,结果为1。

用法:关闭位 (清空位)

和打开特定为类似,有时候需要在不影响其他位的情况下关闭指定的位。假设要关闭变量 flag中的1号位。同样,MASK只有1号位为1.可以这样做:

flag = flag & ~MASK;
可以简化为:
flag &= ~MASK;

例如:假设flag是 00001111,MASK是10110110。下面的表达式:

flag & ~MASK;
即是:
(00001111) & ~(10110110)//表达式
结果为
(00001001) //结果值

用法:切换位
切换位指的是打开已关闭的位,或关闭已打开的位。可以使用按位异或运算符(^)切换位。例如:

0^0=0;   
0^1=1;   
1^0=1;  
1^1=0;

用法:检查位的值
有时候需要检查某为的值。例如,flag中1号位是否被设置为1?不能这样直接比较flag 和 MASK;

if (flag == MASK) //错误的

这样做即使flag的1号位为1 ,其他位值会导致比较结果为假。因此,必须覆盖flag中的其他位,只用1号位和MASK比较:

if ((flag &MASK) == MASK)
puts("WOw!");

移位运算符

**左移:<< **

左移运算符 (<<)将其左侧对象每一位的值向左移其他右侧运算符对象指定的位数。左移运算符对象移出左末端位的值的丢失,用0填充空出的位置。下面的例子中,每一位都左移动两个位置:

(10001010) << 2//表达式
(00101000) //结果值

右移:<<
右移运算符(>>)将其左侧运算符对象每一位的值向右移动其左侧运算符对象指定的位数。左侧运算符对象移出右末端的值丢。对于无符号类型,用0填充空出的位置;对于有符号的类型,其结果取决于机器。

(10001010) >> 2//表达式
(00100010)//在某些系统中的结果值

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

下面是无符号值的例子:

(10001010) >> 2//表达式
(00100010)//所有系统都得到该结果值

用法:移位运算符
移位运算符针对2的幂提供快速有效的乘法和除非:

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

编程示例
我们用移位运算符来编程一个程序,把数字转换为二进制形参。

#include <stdio.h>
#include <limits.h> //提供CHAR_BIT的定义,CHAR_BIT表示每字节的位数

char *itobs(int n, char *ps);
void show_bstr(const char *str);

int main(int argc, char const *argv[])
{

	char bin_str[CHAR_BIT * sizeof(int) + 1];
	int number;

	puts("Enter integers and them in binary.");
	puts("Non-numeric input terminates program.");

	while (scanf("%d",&number) == 1)
	{
		itobs(number,bin_str);
		printf("%d is ",number);
		show_bstr(bin_str);
		printf("\n");
	}

	printf("Bye!\n");
	
	return 0;
}


char *itobs(int n, char *ps)
{
	int i;
	const static int size = CHAR_BIT *sizeof(int);

	for (i = size - 1; i >= 0; i--,n >>= 1)
			ps[i] = (01 & n) + '0';
		ps[size] = '\0';

	return ps;	
}


void show_bstr(const char *str)
{
	int i = 0;

	while (str[i]) //不是一个空字符
	{
		putchar(str[i]);
		if (++i % 4 == 0 && str[i])//4位为一组显示
			putchar(' ');
	}

}


输出结果:

在这里插入图片描述
在这里插入图片描述

扫二维码关注微信公众号,获取技术干货

参考:C Priner Plus

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值