C++位运算

C++中的位运算 基本知识   最近博主在刷Leedcode题,很多人都是采用位运算来解题的,看的我满脸雾水,所以上网收集了一下c++中关于位运算的知识,为此总结一下,有不妥的地方还望指正。   程序中的所有数在计算机内存中都是以二进制的形式储存的。位运算说穿了,就是直接对整数在内存中的二进制位进行操作。比如,and运算本来是一个逻辑运算符,但整数与整数之间也可以进行and运算。举个例子,6的二进制是11... 阅读详情
前言
看到有些人对位运算还存在问题,于是决定写这篇文章作个简要说明。

什么是位(bit)?

很简单,位(bit)就是单个的0或1,位是我们在计算机上所作一切的基础。计算机上的所有数据都是用位来存储的。一个字节(BYTE)由八个位组成,一个字(WORD)是二个字节或十六位,一个双字(DWORD)是二个字(WORDS)或三十二位。如下所示:

  0 1 0 0 0 1 1 1 1 0 0 0 0 1 1 1 0 1 1 1 0 1 0 0 0 1 1 1 1 0 0 0
| |              |               |               |              | |
| +- bit 31      |               |               |       bit 0 -+ |
|                |               |               |                |
+-- BYTE 3 ---- -+---- BYTE 2 ---+---- BYTE 1 ---+--- BYTE 0 -----+
|                                |                                |
+------------ WORD 1 ------------+----------- WORD 0 -------------+
|                                                                 |
+----------------------------- DWORD -----------------------------+

使用位运算的好处是可以将BYTE, WORD 或 DWORD 作为小数组或结构使用。通过位运算可以检查位的值或赋值,也可以对整组的位进行运算。

16进制数及其与位的关系
用0或1表示的数值就是二进制数,很难理解。因此用到16进制数。

16进制数用4个位表示0 - 15的值,4个位组成一个16进制数。也把4位成为半字节(nibble)。一个BYTE有二个nibble,因此可以用二个16进制数表示一个BYTE。如下所示:

NIBBLE   HEX VALUE
======   =========
 0000        0
 0001        1
 0010        2
 0011        3
 0100        4
 0101        5
 0110        6
 0111        7
 1000        8
 1001        9
 1010        A
 1011        B
 1100        C
 1101        D
 1110        E
 1111        F

如果用一个字节存放字母"r"(ASCII码114),结果是:
0111 0010    二进制
  7    2     16进制

可以表达为:'0x72'

有6种位运算:
   &   与运算
   |   或运算
   ^   异或运算
   ~   非运算(求补)
  >>   右移运算
  <<   左移运算

与运算(&)
双目运算。二个位都置位(等于1)时,结果等于1,其它的结果都等于0。
   1   &   1   ==   1
   1   &   0   ==   0
   0   &   1   ==   0
   0   &   0   ==   0

与运算的一个用途是检查指定位是否置位(等于1)。例如一个BYTE里有标识位,要检查第4位是否置位,代码如下:

BYTE b = 50;
if ( b & 0x10 )
    cout << "Bit four is set" << endl;
else
    cout << "Bit four is clear" << endl;

上述代码可表示为:

    00110010  - b
  & 00010000  - & 0x10
 ----------------------------
    00010000  - result

可以看到第4位是置位了。

或运算( | )
双目运算。二个位只要有一个位置位,结果就等于1。二个位都为0时,结果为0。
   1   |   1   ==   1
   1   |   0   ==   1
   0   |   1   ==   1
   0   |   0   ==   0

与运算也可以用来检查置位。例如要检查某个值的第3位是否置位:

BYTE b = 50;
BYTE c = b | 0x04;
cout << "c = " << c << endl;

可表达为:

    00110010  - b
  | 00000100  - | 0x04
  ----------
    00110110  - result

异或运算(^)
双目运算。二个位不相等时,结果为1,否则为0。

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

异或运算可用于位值翻转。例如将第3位与第4位的值翻转:

BYTE b = 50;
cout << "b = " << b << endl;
b = b ^ 0x18;
cout << "b = " << b << endl;
b = b ^ 0x18;
cout << "b = " << b << endl;

可表达为:

    00110010  - b
  ^ 00011000  - ^0x18
  ----------
    00101010  - result

    00101010  - b
  ^ 00011000  - ^0x18
  ----------
    00110010  - result

非运算(~)
单目运算。位值取反,置0为1,或置1为0。非运算的用途是将指定位清0,其余位置1。非运算与数值大小无关。例如将第1位和第2位清0,其余位置1:

BYTE b = ~0x03;
cout << "b = " << b << endl;
WORD w = ~0x03;
cout << "w = " << w << endl;

可表达为:

    00000011  - 0x03
    11111100  - ~0x03  b

    0000000000000011  - 0x03
    1111111111111100  - ~0x03  w

非运算和与运算结合,可以确保将指定为清0。如将第4位清0:

BYTE b = 50;
cout << "b = " << b << endl;
BYTE c = b & ~0x10;
cout << "c = " << c << endl;

可表达为:

    00110010  - b
  & 11101111  - ~0x10
  ----------
    00100010  - result

移位运算(>> 与 <<)
将位值向一个方向移动指定的位数。右移 >> 算子从高位向低位移动,左移 << 算子从低位向高位移动。往往用位移来对齐位的排列(如MAKEWPARAM, HIWORD, LOWORD 宏的功能)。

BYTE b = 12;
cout << "b = " << b << endl;
BYTE c = b << 2;
cout << "c = " << c << endl;
c = b >> 2;
cout << "c = " << c << endl;

可表达为:
    00001100  - b
    00110000  - b << 2
    00000011  - b >> 2

译注:以上示例都对,但举例用法未必恰当。请阅文末链接的文章,解释得较为清楚。

位域(Bit Field)
位操作中的一件有意义的事是位域。利用位域可以用BYTE, WORD或DWORD来创建最小化的数据结构。例如要保存日期数据,并尽可能减少内存占用,就可以声明这样的结构:

struct date_struct {
    BYTE   day   : 5,   // 1 to 31
           month : 4,   // 1 to 12
           year  : 14;  // 0 to 9999
    }date;
    
在结构中,日期数据占用最低5位,月份占用4位,年占用14位。这样整个日期数据只需占用23位,即3个字节。忽略第24位。如果用整数来表达各个域,整个结构要占用12个字节。

| 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 |
   |                             |         |          |
   +------------- year --------------+ month+-- day --+

现在分别看看在这个结构声明中发生了什么

首先看一下位域结构使用的数据类型。这里用的是BYTE。1个BYTE有8个位,编译器将分配1个BYTE的内存。如果结构内的数据超过8位,编译器就再分配1个BYTE,直到满足数据要求。如果用WORD或DWORD作结构的数据类型,编译器就分配一个完整的32位内存给结构。

其次看一下域声明。变量(day, month, year)名跟随一个冒号,冒号后是变量占用的位数。位域之间用逗号分隔,用分号结束。

使用了位域结构,就可以方便地象处理普通结构数据那样处理成员数据。尽管我们无法得到位域的地址,却可以使用结构地址。例如:
date.day = 12;
dateptr = &date;
dateptr->year = 1852;
位运算C/C++ 位运算的应用非常广泛,它们通常在需要处理大量数据或对性能有严格要求的场合中非常有用。由于位运算直接操作内存中的位,因此它们通常比等效的算术或逻辑运算更快。位运算是一种直接对整数的二进制位进行操作的方法。下面我将通过一个详细的示例来解释每个位运算符的工作原理,并提供一种可视化的方法来帮助理解。位运算是C和C++编程语言中的一种操作,它直接对整数的。将操作数的每一位取反,0变1,1变0。可视化过程:只有当两个位都是1时,结果位才为1。可视化过程:只要有一个位是1,结果位就为1。对应位都为1时,结果才为1。 阅读详情

相关推荐

C++教程之位运算

这篇文章主要讲述来C++中的位运算,更多文章可以关注公众号QStack。

QStack的博客 3357

c++位运算(收藏用)

前言看到有些人对位运算还存在问题,于是决定写这篇文章作个简要说明。什么是位(bit)?很简单,位(bit)就是单个的0或1,位是我们在计算机上所作一切的基础。计算机上的所有数据都是用位来存储的。一个字节(BYTE)由八个位组成,一个字(WORD)是二个字节或十六位,一个双字(DWORD)是二个字(WORDS)或三十二位。如下所示:0 1 0 0 0 1 1 1 1 0 0 0 0 1 1 1 0

370

c++的位运算总结

最近在刷位运算的题目,经常用的位运算还比较熟悉,但对于左移、右移运算符和其应用实践有待学习。这里统一总结一下C++的位运算。 学习整理自此链接处 1.总表 运算符 名称 作用 & 按位与 两个操作数同时为1,结果为1 | 按位或 两个操作数只要有一个为1,结果为1 ~ 按位非 按位取反,操作数为1,结果为0;操作数为0,结果为1 ^ 按位异或 两个操作数相同,结果为0;两个操作数不同,结果为1 << 左移 右侧空位补0,左移一位相当于将原数扩大两倍 &

HFGD2019的博客 1760

C++篇——位运算

位运算的用处: 判断某一位是否为1 只改变其中某一位,而保持其他位都不变。 C/C++语言提供了六种位运算符来进行位运算操作: & 按位与 (双目) | 按位或 (双目) ^ 按位异或 (双目) ~ 按位非(取反) (单目) << 左移 (双目) >> 右移 (双目) 按位与 “&” 概念: 将参与运算的两操作数各对...

weixin_45273807的博客 1839

C++位运算是补码形式

C++位运算是用的补码 用例说明 在C++中运算93&-8得88;但是用原码来算的话,结果是8; 所以在C++中,位运算是作用在补码上的。 如果都是正数,应该结果一致,因为补码跟原码相同。 -8的原码: 10000000000000000000000000001000 -8的反码:11111111111111111111111111110111 -8的补码:11111111111111111111111111111000 93的原码:00000000000000000000000001011101

weixin_42172720的博客 1073

基于多智能体架构的AI自动化渗透测试平台PentAGI部署与实战

自动化渗透测试是网络安全领域提升效率、应对复杂威胁的关键技术。其核心原理在于通过程序化脚本或智能系统模拟攻击者行为,对目标系统进行安全评估。该技术能显著降低人工重复劳动,实现7x24小时持续监控与测试,其价值在于将安全专家从繁琐的扫描、信息收集中解放出来,专注于高级威胁分析与策略制定。在实际应用中,自动化渗透测试广泛应用于企业安全自评估、红蓝对抗演练及DevSecOps流程。本文聚焦于一个名为PentAGI的先进平台,它采用多智能体(Multi-Agent)系统架构,集成了知识图谱和向量数据库,实现了从侦察

weixin_30294295的博客 608

C/C++ 按位运算

利用按位运算节省内存空间

罗马尼亚硬拉 1360

华为手环实时心率数据导出到UWP项目中

hello大家好呀O(∩_∩)O最近在做毕设 其中有个小功能要用到实时心率数据。查找网上的资料发现只有小米手环的实时心率数据导出但是没有华为手环的,我试了华为手环但是并不能行得通哈哈哈。现在分享一下华为手环实时心率数据导出的代码。

apple_63713858的博客 1582

c++之位运算(详解,初学者绝对能看懂)

目录 一 位运算符号 移位运算: 二 常用技巧: 三 运算符号优先级: 四 位运算常用技巧 1 判断奇偶性 2 求a的b次方 3 找处未重复的数 4用O(1)时间检测整数n是否是2的幂次. 5计算在一个 32 位的整数的二进制表示中有多少个 1 6二进制状态压缩 7二进制优化递归 8 一道经典题 一 位运算符号 & 按位与 如果两个相应的二进制位都为1,则该位的结果值为1,否则为0 | 按位或 两个相应的二进制位中只要有一个为1...

m0_64183293的博客 2万+

逍遥模拟器改真机参数全指南:从ARM伪装到电池传感器模拟

本文提供逍遥模拟器深度伪装实战指南,重点讲解如何通过修改ARM架构、系统属性和模拟传感器数据,使其在硬件信息、电池状态等维度逼近真实设备,有效规避应用检测。文章详细介绍了使用Magisk模块、LSPosed框架进行设备指纹伪装和动态数据模拟的策略,帮助用户实现从静态信息到动态行为的全方位真机模拟。

weixin_29279101的博客 452

Amesim基础篇-元件详解-流体库管路

Amesim基础篇-元件详解-流体库管路

2201_75375391的博客 4524

C++位运算详解

前言 以前收藏过一篇讲C++位操作的文章,这次博客搬家,以前的数据都没有保留,整理谷歌网站管理后台的时候,发现不时的还有网友有在查找这篇文章。所以,疯刀也来弄个简单的教程,讲讲位操作的用途和魅力吧。 位简介 位是数据存储的最小单位。在 计算机中的二进制数系统中,位,简记为b,也称为比特,每个0或1就是一个位(bit)。 位操作详解 我们先来看看位运

hao448609471的专栏 1088

AD7768与STM32F439的硬件设计避坑指南:如何优化高精度ADC系统的电源与PCB布局

本文详细解析了AD7768与STM32F439在高精度ADC系统硬件设计中的关键问题与优化方案。从电源系统设计、PCB布局到基准电压选型,提供了实用的避坑指南和实测数据,帮助工程师提升系统性能至110dB动态范围。特别强调了SPI信号布线和电源滤波对ADC精度的重要影响。

sugar的博客 735

C++—位运算

C++位运算简介、示例和应用,位匀速主要包括与、或、异或、非、左移和右移;在位运算非的介绍中描述了负数的存储方式和补码的概念。

shouhu010的博客 4205

分布式光纤传感(DFOS)DTS/DAS/DSS 三合一:10公里管线监测实战与数据解读

本文详细介绍了分布式光纤传感(DFOS)技术在10公里管线监测中的实战应用,通过DTS(温度)、DAS(振动)、DSS(应变)三合一系统,实现对管线健康状态的立体感知。文章涵盖工程部署、数据采集、多物理量数据融合及噪声抑制等关键技术,展示了如何通过一根光纤完成复杂监测任务,显著提升管线安全性和维护效率。

weixin_29168153的博客 315

【AI智能体】基于OpenCode 搭建Skills环境与项目实战开发详解

基于OpenCode 搭建Skills环境与项目实战开发详解

congge 8899

【C++】位运算

位运算、按位与、按位或、异或、取反、左移、右移、补码

weixin_43510208的博客 1585

指纹浏览器降维打击(下):Cloudflare Turnstile 与 hCaptcha 的底层交互逻辑

本文将深度拆解:Turnstile 与 hCaptcha 的 Iframe 沙箱通信机制,动态混淆 JS 与 PoW(工作量证明)的物理破解法则,以及如何通过 C++ 底层事件合成与环境基因强绑定,实现验证码的“无感过验”。

数据知道的博客 422

C++算法学习:位运算

在前面C语言的部分中,我们已经学习并了解了位置运算的相关内容。想详细了解的可以参考以上这篇代码。而接下来我们将就位运算的思想来进行算法练习相关算法代码已经上传至作者的个人gitee中。

2401_89119815的博客 1123

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

【C++指南】位运算知识详解

在C++编程中,位运算是一种直接对二进制位进行操作的运算方式。它不仅可以提高程序的运行效率,还能解决一些特定的算法问题,如“只出现一次的数字”系列题目。 下面将详细介绍C++位运算的相关知识,包括位运算符的使用、规则以及实战使用技巧。

倔强的石头的博客 1851

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

【C++算法/学习】:位运算详解,看这篇就够了

✨🌏📃:在计算机内部,数是以「二进制(Binary)」的形式来进行存储。位运算就是直接对数的二进制进行计算操作,在程序中使用位运算进行操作,会大大提高程序的性能。:由 0 和 1 两个数码来表示的数。二进制数中每一个 0 或每一个 1 都称为一个「位(Bit)」。1. 位运算的运算符2. 位运算的性质。

island1314的博客 9114

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

C++中负数的位运算

C++C++中负数的位运算C++负数的位与运算C++负数的位或运算 C++中负数的位运算 C++负数的位与运算 C++中负数的位与运算是先将负数用补码表示,再进行按位取与的运算,再将运算的结果从补码表示转化为十进制表示,再输出出来 以下的是一个简单的例子: int main() { // C++中负数的位与运算 int number1 = 3; int number2 ...

GorMing 的博客 5941

位运算.cpp

/*位运算*位都有编号,从0开始;*(高低) *位是最小的数据单元,只能保存一个二进制数据(0或1),八个为一个字节,即char型占8位,int型占32位,double占64位,64位机一个指令周期可处理64个位,所以64为指针占8个字节,一个二进制占1位,八进制占三位,十六进制占四位*/# include using namespace std;int main(){ union A { in

东哥的博客 607
上一篇: DWORD,BYTE,句柄类型
下一篇: 深入学习JavaScript: apply 方法 详解(转)——非常好
Vivian_Chang
博客等级 码龄14年 2粉丝 1原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值