导读在进行某些算法的C语言编程的时候需要使几种不同类型的变量存放到同一段内存单元中也就是使用覆盖技术几个变量互相覆盖这种几个不同的变量共同占用一段内存的结构在C语言中被称作“共用体”类型结构简称共用体也叫联合体
在C++中有一种类型叫做联合体(也叫共用体)它的关键字为union在使用上与结构struct非常相似可以包含任何的结构类型数据但它又有一个非常独特的特性那就是所有的数据都指向一个地址
这个意思你可以理解为联合体中的所有数据都是引用一个内存块中相同地址的数据当我们改变这个联合体内任何一种数据的值时其他的数据的值都会随之改变
这对于未知类型的数据非常有效你可以使用联合体装载一个数据然后分析其数据是否有效或者可以对某些特殊的类型进行位运算获取其特殊位置的数值
但在VBNET或C#中根本没有union关键字让我们声名联合体但该怎么做才能声名联合体呢?
这需要用到结构属性!
让我们看看如何将下面的C++联合体代码转换为一个VBNET的联合结构吧!
- unionmyunion
- {
- charb;//单字节整数在c语言中用char类型来表示单字节整数
- shorts;//双字节整数
- inti;//四字节整数
- }
这个联合体大小为个字节其各个数据分别表示为单字节双字节四字节的整数在运行期间其任何数据的改变都会影响其他数据
- ImprotsSystemRuntimeInteropServices引入运行时非托管数据管理服务
引入结构属性精确控制结构中元素的位置
- <StructLayout(LayoutKindExplicit)>_
- StructureMyUnion
- 设置字段的偏移值设为即可
- <FieldOffset()>DimbAsByte单字节整数
- <FieldOffset()>DimsAsShort双字节整数
- <FieldOffset()>DimiAsInteger四字节整数
- EndStructure
这就是在NET中设置联合结构的方法C#中于VBNET中的设置方法雷同这里就不做赘述了
下面来介绍联合体的特性应用就以上面我们刚才声名的联合体结构为例下面的代码将为我们演示联合体的特性
- DimMUAsNewMyUnion
- MsgBox(StringFormat("{}{}{}"MUbMUsMUi))
- MUs=IntMaxValue
- MsgBox(StringFormat("{}{}{}"MUbMUsMUi))
- MUb=
- MsgBox(StringFormat("{}{}{}"MUbMUsMUi))
- MUi=
- MsgBox(StringFormat("{}{}{}"MUbMUsMUi))
上面的代码可以更直观地显示数据在内存中的变化每当改变联合数据时其他的数据也会随着内存的变化而变化
当然使用联合体也有限制那就是NET的联合体只适用于值类型无法应用在引用类型和指针中你无法设置字符串(String)或是数组进入联合类型这一点需要非常的注意!
当然NEt中的联合结构体并不只有上面的用法你可以发挥自己的想象力比如可以
- <StructLayout(LayoutKindExplicit)>_
- StructureMyUnion
- <FieldOffset()>DimbAsByte
- <FieldOffset()>DimbAsByte
- <FieldOffset()>DimbAsByte
- <FieldOffset()>DimbAsByte
- <FieldOffset()>DimiAsInteger
- <FieldOffset()>DimuiAsUInteger
- EndStructure
这个结构可以获取一个有或无符号的四个字节整数每一个字节的数据而不需要自己写算法来分析了
测试代码
Code
- DimMUAsMyUnion
- MsgBox(MUi&":"&MUui):
- MsgBox(StringFormat("{}{}{}{}"Hex(MUb)Hex(MUb)Hex(MUb)Hex(MUb)))
- MUb=:MUb=:MUb=:MUb=
- MsgBox(StringFormat("{}{}{}{}"Hex(MUb)Hex(MUb)Hex(MUb)Hex(MUb)))FFFFFFFF
- MsgBox(MUi&":"&MUui):