C#读取字节数组某个位的值的具体实现方法

 更新时间:2026年01月04日 09:40:34   作者:工业程序猿老赵  
字节数组中提取指定偏移量字节的指定位的值(对应 PLC 中 1 个字节对应 8 个布尔值的场景,如 I0.0~I0.7 对应 1 个字节的 bit0~bit7),核心是通过位运算实现,下面详细讲解具体方法和实现,需要的朋友可以参考下

一、核心原理

  1. 先通过 bytes[offset] 获取字节数组中指定偏移量(offset)的单个字节(对应 PLC 中的 1 个字节地址);
  2. 再通过 按位与(& 运算 + 位左移(<< 运算,提取该字节中指定位(bitIndex,范围 0~7,0 表示最低位 / 最右边,7 表示最高位 / 最左边)的值;
  3. 判定规则:运算结果非 0 表示该位为 1(对应 C# true),运算结果为 0 表示该位为 0(对应 C# false)。

二、关键表达式(提取单个位的值)

这是提取指定位的核心代码,直接可复用:

// 核心表达式:提取 bytes 数组中 offset 偏移量字节的 bitIndex 位的值
bool bitValue = (bytes[offset] & (1 << bitIndex)) != 0;

表达式逐部分拆解

部分含义说明
bitIndex要提取的位索引,范围 0~7(必须满足 0 ≤ bitIndex ≤ 7,否则会出错)
1 << bitIndex把数字 1 左移 bitIndex 位,生成一个 “仅目标位为 1,其余位为 0” 的掩码(例如 bitIndex=2 时,1<<2=4,对应二进制 00000100
bytes[offset] & (1 << bitIndex)按位与运算:只有 “目标位同时为 1” 时,结果才非 0,其余情况结果为 0(精准筛选目标位的值)
!= 0将位运算结果转换为 C# 布尔值:非 0 → true(位值为 1),0 → false(位值为 0)

三、完整代码示例

下面提供可直接运行的 C# 代码,包含字节数组定义、位提取方法、场景演示:

using System;

class PlcBitExtraction
{
    static void Main(string[] args)
    {
        // 示例:从 PLC 读取的字节数组(假设 bytes[0] = 0x05,对应二进制 00000101)
        byte[] plcBytes = new byte[] { 0x05, 0x12, 0x34 };

        // 需求1:提取 offset=0(第1个字节)、bitIndex=0(最低位)的值
        int offset1 = 0;
        int bitIndex1 = 0;
        bool bit1 = ExtractBitFromBytes(plcBytes, offset1, bitIndex1);
        Console.WriteLine($"字节{offset1}的位{bitIndex1}值:{bit1}(对应二进制位1)");

        // 需求2:提取 offset=0、bitIndex=1 的值
        int bitIndex2 = 1;
        bool bit2 = ExtractBitFromBytes(plcBytes, offset1, bitIndex2);
        Console.WriteLine($"字节{offset1}的位{bitIndex2}值:{bit2}(对应二进制位0)");

        // 需求3:提取 offset=0、bitIndex=2 的值
        int bitIndex3 = 2;
        bool bit3 = ExtractBitFromBytes(plcBytes, offset1, bitIndex3);
        Console.WriteLine($"字节{offset1}的位{bitIndex3}值:{bit3}(对应二进制位1)");

        // 需求4:提取 offset=1、bitIndex=3 的值(bytes[1]=0x12 → 二进制 00010010)
        int offset4 = 1;
        int bitIndex4 = 3;
        bool bit4 = ExtractBitFromBytes(plcBytes, offset4, bitIndex4);
        Console.WriteLine($"字节{offset4}的位{bitIndex4}值:{bit4}(对应二进制位1)");
    }

    /// <summary>
    /// 从字节数组中提取指定偏移量、指定位索引的位值
    /// </summary>
    /// <param name="bytes">原始字节数组(从 PLC 读取的字节流)</param>
    /// <param name="offset">字节偏移量(数组索引,从0开始)</param>
    /// <param name="bitIndex">位索引(0~7,0=最低位,7=最高位)</param>
    /// <returns>位值(true=1,false=0)</returns>
    static bool ExtractBitFromBytes(byte[] bytes, int offset, int bitIndex)
    {
        // 合法性校验:防止数组越界和位索引超出范围
        if (bytes == null)
            throw new ArgumentNullException(nameof(bytes), "字节数组不能为null");
        if (offset < 0 || offset >= bytes.Length)
            throw new ArgumentOutOfRangeException(nameof(offset), "字节偏移量超出数组范围");
        if (bitIndex < 0 || bitIndex > 7)
            throw new ArgumentOutOfRangeException(nameof(bitIndex), "位索引必须在0~7之间");

        // 核心:位运算提取指定位
        byte targetByte = bytes[offset]; // 获取指定偏移量的字节
        int mask = 1 << bitIndex;        // 生成位掩码
        return (targetByte & mask) != 0; // 按位与运算,判定位值
    }
}

四、运行结果说明

上述代码中,plcBytes[0] = 0x05(十六进制)→ 对应二进制 00000101,运行后输出:

plaintext

字节0的位0值:True(对应二进制位1)
字节0的位1值:False(对应二进制位0)
字节0的位2值:True(对应二进制位1)
字节1的位3值:True(对应二进制位1)

完全匹配二进制位的实际值,验证了提取逻辑的正确性。

五、补充说明

  1. 位索引顺序:PLC 中常用的位编号(如 I0.0、I0.1)通常对应 bitIndex=0bitIndex=1,与上述代码的位索引一致;
  2. 批量提取:若需提取 1 个字节对应的 8 个位,可通过循环 bitIndex 从 0 到 7 依次调用提取方法;
  3. PLC 场景适配:该方法完全适配 Sharp7、S7NetPlus 等主流 PLC 通信库,可直接集成到 PLC 数据读取业务中。

总结

  1. 核心表达式:(bytes[offset] & (1 << bitIndex)) != 0(快速提取指定位的值);
  2. 关键运算:按位与(&)用于筛选目标位,位左移(<<)用于生成位掩码;
  3. 位索引范围:0~7(0 最低位,7 最高位),偏移量 offset 为字节数组的索引;
  4. 实际使用时需增加合法性校验,避免数组越界和无效位索引。

到此这篇关于C#读取字节数组某个位的值的具体实现方法的文章就介绍到这了,更多相关C#读取字节数组某个位的值内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Unity实现喷漆效果

    Unity实现喷漆效果

    这篇文章主要为大家详细介绍了Unity实现喷漆效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-07-07
  • 关于Unity中RectTransform与transform的区别

    关于Unity中RectTransform与transform的区别

    这篇文章主要介绍了Unity中RectTransform与transform的区别,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-01-01
  • 基于C#实现屏幕取色器

    基于C#实现屏幕取色器

    这篇文章主要为大家详细介绍了如何利用C#实现简易的屏幕取色器,文中的示例代码讲解详细,对我们学习C#有一定的帮助,感兴趣的小伙伴可以了解一下
    2022-12-12
  • C#实现网络通信共享库NetShare的使用示例

    C#实现网络通信共享库NetShare的使用示例

    本文主要介绍了C#实现网络通信共享库NetShare,网络通信共享库NetShare用于保证客户端与服务器通信数据包的规范和统一,感兴趣的可以了解一下
    2023-11-11
  • C#中的委托和事件详解

    C#中的委托和事件详解

    本文详细讲解了C#中的委托和事件,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-07-07
  • C#基于时间轮调度实现延迟任务详解

    C#基于时间轮调度实现延迟任务详解

    在很多.net开发体系中开发者在面对调度作业需求的时候一般会选择三方开源成熟的作业调度框架来满足业务需求,但是有些时候可能我们只是需要一个简易的延迟任务。本文主要分享一个简易的基于时间轮调度的延迟任务实现,需要的可以参考一下
    2022-12-12
  • C#图片按比例缩放实例

    C#图片按比例缩放实例

    这篇文章主要为大家详细介绍了C#图片按比例缩放的实例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-03-03
  • 利用C#实现SSLSocket加密通讯的方法详解

    利用C#实现SSLSocket加密通讯的方法详解

    这篇文章主要给大家介绍了关于如何利用C#实现SSLSocket加密通讯的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2020-07-07
  • 调整C#中数组大小的方法

    调整C#中数组大小的方法

    数组存储多个相同类型的一种非常常用的数据结构,它长度是固定,也就是数组一旦创建大小就固定了,C# 数组不支持动态长度,那在C#中是否有方法可以调整数组大小呢?本文将通过示例介绍一种调整一维数组大小的方法,需要的朋友可以参考下
    2024-06-06
  • C#读取静态类常量属性和值的实例讲解

    C#读取静态类常量属性和值的实例讲解

    在本篇文章里小编给各位分享的是关于C#读取静态类常量属性和值的实例讲解,有兴趣的朋友们可以学习下。
    2020-03-03

最新评论