您的位置:首页 > 编程语言 > C语言/C++

C#正真实现C++中的数值型位域(非位标志)

2015-04-16 15:28 218 查看
C++中的位域成员有2种用途。一种是存放位标志的,比如下面这种。

struct flags
{
unsigned int flag1:1;
unsigned int flag2:1;
}

C#中可以很方便地用 [Flags] Enum 实现,网上找C#实现位域的都是这种。

还有一种是存放数值的,比如今天碰到一个问答,是下面这样的结构。

struct MWORD
{
unsigned int m_nBase:30;
unsigned int m_nMul:2;
}

原先C++中Mul成员的取值范围是0..3。

假如还用 [Flags] Enum 实现,按位与操作后取值是零散的{0,0x40000000,0x80000000,0xC0000000},用起来不方便。

需要把原先C++自动实现的各种位操作封装到属性中:

//C#的控制台工程
using System;
using System.Runtime.InteropServices;

namespace ConsoleApplication1
{
[StructLayout(LayoutKind.Sequential)]
public struct MWORD
{
public uint value; //暴露出来方便调试,最终版应该是private的。
public uint Base
{
get
{
return this.value & 0x3FFFFFFF;
}
set
{
this.value = (this.value & 0xc0000000) | (value & 0x3FFFFFFF);
}
}
public uint Mul
{
get
{
return (this.value >> 30) & 0x00000003;
}
set
{
this.value = (this.value & 0x3FFFFFFF) | ((value & 0x00000003)<<30);
}
}
}
class Program
{
static void Main(string[] args)
{
MWORD v = new MWORD();
Console.WriteLine("SizeOf()={0}",Marshal.SizeOf(v));
v.value = 0xffffffff;
Console.WriteLine("value=0x{0:X8}, Base={1}, Mul={2}", v.value, v.Base, v.Mul);
v.Base = 0x23456789;
Console.WriteLine("value=0x{0:X8}, Base={1}, Mul={2}", v.value, v.Base, v.Mul);
v.Mul = 2;
Console.WriteLine("value=0x{0:X8}, Base={1}, Mul={2}", v.value, v.Base, v.Mul);
Console.ReadLine();
}
}
}

输出:

SizeOf()=4
value=0xFFFFFFFF, Base=1073741823, Mul=3
value=0xE3456789, Base=591751049, Mul=3
value=0xA3456789, Base=591751049, Mul=2
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: