ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【C语言】位运算

2021-12-04 19:34:00  阅读:138  来源: 互联网

标签:count 0000 运算 int C语言 1111 num 按位


文章目录

前言:

C语言的位运算有6种:按位与&按位或|按位取反~按位异或^按位左移<<按位右移>>

注意:能够参与位运算的操作数必须是整型,以补码形式进行按位运算


(一)按位与& (双目运算符)

0 | 1 ⇒ 0
1 | 0 ⇒ 0
1 | 1 ⇒ 1
0 | 0 ⇒ 0

(1)迅速清零

#include <stdio.h>

int main()
{
	int a = 15;
	a = a & 0;
	printf("a = %d\n", a);
	return 0;
}

在这里插入图片描述
结果:
在这里插入图片描述

从这还不足以看出按位与&的真正魅力,主要做作用就在下面

(2)保留指定位

#include <stdio.h>

int main()
{
	int a = 15;
	a = a & 6;
	printf("a = %d\n", a);
	return 0;
}

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

(3)判断奇偶性

补码的最低位是0,就是偶数,1是奇数

所以使用任意数和1进行按位与,即(num & 1) == 0 ? 偶数 : 奇数

注意:逻辑运算符的优先级高是7,按位运算符的优先级低是9

我们来输出下[1 - 100] 之间的偶数

#include <stdio.h>
int main()
{
	for (int i = 1; i <= 100; i++)
	{
		if ((i & 1) == 0)
		{
			printf("%-4d", i);
		}
	}
	return 0;
}

在这里插入图片描述

拓展:
按位与&不光能判断奇偶性,而且还能判断能够被2^n (n>=0)整除的数
总结:

  • 判断一个数num能否被2^n整除,使用(num & (2^n - 1))) == 0 ? 偶数 : 奇数
  • 例如:一个整数内否被4整除
#include <stdio.h>
int main()
{
   for (int i = 1; i <= 100; i++)
   {
   	if ((i & 3) == 0)
   	{
   		printf("%-4d", i);
   	}
   }
   return 0;
}

在这里插入图片描述

(二)按位或 | (双目运算符)

0 | 1 ⇒ 1
1 | 0 ⇒ 1
1 | 1 ⇒ 1
0 | 0 ⇒ 0

(1)修改数据的指定位的值

例:把char类型的十进制100的第4个二进制位改成1
把100 : 1100 0100
使用 | : 0000 1000
结果: 1100 1100(108)

#include <stdio.h>

int main()
{
	char a = 100;
	a = a | 0x08;
	return 0;
}

在这里插入图片描述

(三)按位取反~(单目运算符)

~0 ⇒ 1
~1 ⇒ 0

(1)方便表示一个数字,通常和& | 结合使用

#include <stdio.h>

int main()
{
	int a = 0x12345678;
	//  0001 0010 0011 0100 0101 0110 0111 1000
	//& 1111 1111 1111 1111 1111 1111 0000 0000
	//将a的后2位78变成00
	// 0001 0010 0011 0100 0101 0110 0000 0000
	int b = a & 0xffffff00;
	printf("b = %x\n", b);
	//第二种表示:1111 1111 1111 1111 1111 1111 0000 0000
	//~ 0000 0000 0000 0000 0000 0000 1111 1111
	//~255
	b = a & ~255;
	printf("b = %x\n", b);
	return 0;
}

在这里插入图片描述

(四)按位异或^(双目运算符)

0 ^ 0 ⇒ 0
0 ^ 1 ⇒ 1
1 ^ 0 ⇒ 1
1 ^ 1 ⇒ 0

(1)按位异或的规律

  1. 结合律:a ^ (b ^ c) == (a ^ b)^ c
  2. 交换律:a ^ b == b ^ a
  3. 归零律:a ^ a == 0
  4. 恒等率:a ^ 0 == a
  5. 自反性:a ^ b ^ a == b

(2)判断两个数是否相等

//a == b;
//(a - b) == 0;
//(a ^ b) == 0;

(3)交换两个数

#include <stdio.h>
int main()
{
	int a = 10;
	int b = 20;
	
	a = a ^ b;	
	b = a ^ b;	// a ^ b ^ b == a
	a = a ^ b;	// a ^ b ^ a == b
	
	printf("a = %d, b = %d\n", a ,b);
	return 0;
}

在这里插入图片描述

(4)一个整型数组里的value只出现了一次,其余数据都是两次,请找到这个数

int main()
{
	int arr[] = {2, 1, 5, 4, 2, 1, 6, 5, 6};
	int len = sizeof(arr) / sizeof(arr[0]);
	int ret = 0;
	for (int i = 0; i < len; i++)
	{
		ret = ret ^ arr[i];
	}

	printf("%d\n", ret);
	return 0;
}

在这里插入图片描述

(四)按位左移<<,按位右移>>

<<左移:最低位填充0

>>右移:

  • 有符号数最高位填充符号位
  • 无符号数最高位填充0

练习题:计算一个整型数对应的二进制数中1的个数

(1)解法一
#include <stdio.h>
//得到一个整数二进制中的1的个数
int GetOneNum(int num)
{
	//计算二进制位个数
	int bit_num = sizeof(num) * 8;
	int count = 0;	//计数

	while (bit_num--)
	{
		if ((num & 1) == 1)
		{
			count++;
		}
		num >>= 1;
	}
	return count;
}

int main()
{
	int test = 0xd2;	//1101 0010
	printf("number of 1 : %d\n", GetOneNum(test));
	return 0;
}
(2)解法二
int GetOneNum(unsigned int num)
{
	int count = 0;	//计数

	while (num != 0)
	{
		if ((num & 1) == 1)
		{
			count++;
		}
		num >>= 1;
	}
	return count;
}
(3)解法三
int GetOneNum(int num)
{
	int count = 0;	//计数

	while (num != 0)
	{
		num = num & (num - 1);
		count++;
	}
	return count;
}
(4)解法四:查表法
/*
* 我们将四个位作为一个位移动的基本单元
* 得到每个单元的所有可能,然后四位四位的与运算
*/
int GetOneNum(int num)
{
	int num_4bit = sizeof(num) * 2;	//一字节 == 2个十六进制位
	int count = 0;	 
	//四位一个单元的所有可能     //计数
	//0000                      0
	//0001                      1
	//0010                      1
	//0011                      2
	//0100						1
	//0101						2
	//0110						2
	//0111						3
	//1000						1
	//1001						2
	//1010						2
	//1011						3
	//1100						2
	//1101						3
	//1110                      3
	//1111						4
	while (num_4bit--)
	{
		count = count + "0112122312232334"[num & 0x0f] - '0';
		num >>= 4;
	}
	return count;
}

标签:count,0000,运算,int,C语言,1111,num,按位
来源: https://blog.csdn.net/xiaoxiaoguailou/article/details/121713498

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有