IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 【C语言】位运算 -> 正文阅读

[C++知识库]【C语言】位运算

前言:

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;
}
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-12-05 11:51:56  更:2021-12-05 11:52:44 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 11:02:57-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码