用起来真的方便 转摘如下:

C#借助FieldOffset属性实现共用体与强制类型转换

这两天被C#的强制类型转换弄得有点不习惯。事出如此。

在C#中,我打算读二进制文。文件的结构很简单,一连串的紧密存储的int32值,以二进制方式存放。现在我希望随机读取第n个int32开始的i个值,并读入到数组中。结果查一下C#只能读到byte[]中,要不就是一个个读出来循环放int[]。追求效率的我当然不希望这样,如果能像C++那样将byte[]强制转换成int[]就好了。例如:

  1. char tmp[64];       // 16个int。相当于C#的 byte[] tmp = new int[64];
  2. int* dat;       // dat的指针。相当于C#的 int[] dat;
  3. ifstream IF(...);   // 标准文件输入流。相当于C#的 FileStream FS = new FileStream(...);
  4. IF.read(tmp, 64);   // 读取64个字节。  相当于C#的 FS.Read(tmp,0,64);
  5. dat = (int*)tmp;    // 将tmp数组的首地址转为int类型,则数组以4个字节为一个int转换为int型的数组。
  6. // 数据在内存上没有任何变化,因为数据本来就是int型的。
  7. // 关键是这一步在C#中无法直接实现。
  8. for (int i = 0; i < 16; i++)
  9. cout << dat[i] << " "; // 输出数据。相当于C#的 Console.Write(dat[i]+" ");

在C#中无法直接实现,为此我想了好些办法,也查了好久,直到我见到了这样的代码:

  1. using System;
  2. using System.IO;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. // 提供各种各样支持 COM 互操作 及平台调用服务的成员
  7. using System.Runtime.InteropServices;
  8. namespace test
  9. {
  10. class Program
  11. {
  12. // StructLayout使设计者可以控制类或结构的数据字段的物理布局
  13. // Explicit与FieldOffset一起可以控制每个数据成员的精确位置
  14. [StructLayout(LayoutKind.Explicit)]
  15. public struct S1
  16. {
  17. // FieldOffset控制字段所在的物理位置偏移为0
  18. [FieldOffset(0)]
  19. public byte[] a;
  20. // 同样偏移为0,开始位置与a重叠了。
  21. [FieldOffset(0)]
  22. public int[] b;
  23. }
  24. static void Main(string[] args)
  25. {
  26. S1 s = new S1(); // 要new,不然b会报“使用了可能未赋值的字段”
  27. s.a=new byte[64];
  28. FileStream FS = new FileStream("E:\\test.txt", FileMode.Open);
  29. // 以s.a来接收文件的数据
  30. FS.Read(s.a,0,64);
  31. // 自己保证读b的时候不要越界
  32. for (int i = 0; i < 16; i++)
  33. Console.Write(s.b[i]+" "); // 以b来使用数据
  34. Console.ReadKey();
  35. }
  36. }
  37. }

原理实际上跟C++一样,将一个int[]型的变量指向与byte[]型变量相同的内存区域,跟C++中将dat指向char数组的首地址是一样的。同样,这样的结构体功能与C++的共用体是一样的,即一个结构可以作为多种数据类型,而具体是什么类型视情况而定。

测试所使用的文件就不上传了,有WinHex的可以自己编辑一个,没有的也可以写程序将从0xF到0x0的16个数以二进制方式输出到文件中。文件的内容用WinHex打开以16进制显示应该如下:

c# 如何 使用共用体的更多相关文章

  1. C语言共用体、大小端、枚举

    1.共用体和结构体的相同和不同 (1)相同点就是操作语法几乎相同.(2)不同点是本质上的不同.struct是多个独立元素(内存空间)打包在一起:union是一个元素(内存空间)的多种不同解析方式. # ...

  2. C语言共用体(Union)

    通过前面的讲解,我们知道结构体(Struct)是一种构造类型或复杂类型,它可以包含多个类型不同的成员.在C语言中,还有另外一种和结构体非常类似的语法,叫做共用体(Union),它的定义格式为: uni ...

  3. 瘋子C语言笔记(结构体/共用体/枚举篇)

    (一)结构体类型 1.简介: 例: struct date { int month; int day; int year; }; struct student { int num; char name ...

  4. C++结构、共用体、枚举

    一.结构 结构是C++OOP的基石.学习有关结构的知识僵尸我们离C++的核心OOP更近. 结构是用户定义的类型,同一个结构可以存储多种类型数据,这使得将一个事物的不同属性构成一个对象成为了可能.另外C ...

  5. 【C语言入门教程】7.4 共用体

    7.4 共用体 共用体又称为联合体,是由不同的数据类型组成的一个整体.与结构体不同的是,共用体每次只能使用其中一个成员.结构体的总长度是结构体所有成员长度之和,共用体的总长度是其中最长一个数据类型的长 ...

  6. C语言之共用体

    最近在复习C语言,特再次记录: 有时需要将几种不同类型的变量存放到同一段内存单元中.如一个int.float.char放在同一个地址开始的内存单元中.,也就是使用覆盖技术,几个变量相互覆盖,称之为共用 ...

  7. 不可或缺 Windows Native (8) - C 语言: 结构体,共用体,枚举,类型定义符

    [源码下载] 不可或缺 Windows Native (8) - C 语言: 结构体,共用体,枚举,类型定义符 作者:webabcd 介绍不可或缺 Windows Native 之 C 语言 结构体 ...

  8. C语言-10-位域与共用体

    位域 在某种特定情况下,一个结构体中的多个变量只使用各自存储空间的几位,而其他位从来不使用.这种情况下,可以使用位域来限定每个变量的用来存储数据的位宽. 作用 限定结构体中变量用来存放数据的位宽,即使 ...

  9. C语言 共用体

    //共用体 union #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #includ ...

  10. 转:union 联合体(共用体)

    转自:http://blog.csdn.net/xiao3404/article/details/22276485 2.共用体 2.1共用体的概念 共用体是一种构造类型的数据结构.在一个“共用体”内可 ...

随机推荐

  1. aliplayer 视频播放报错

    问题总结: 1.引用 阿里库时href和src 文件路径不加http <link rel="stylesheet" href="//g.alicdn.com/de/ ...

  2. Codeforces 1045B Space Isaac - 数论 - Hash

    题目传送门 传送门I 传送门II 传送门III 题目大意 给定将$\left \{ 0, 1, \dots, m - 1\right \}$分成了不相交的两个非空集合$A$和$B$,给定$A$,问存在 ...

  3. jQuery validator plugin之Validator

    Validator.destroy() Destroys this instance of validator freeing up resources and unregistering event ...

  4. R语言-默认镜像设置

    问题1:如何设置默认镜像 你希望下载某些R包,因此希望设定默认的CRAN网站镜像,这样R每次下载时不需要你选择镜像. 解决方案 该方案要求用户R系统中包含一个.Rprofile文件,如方法3.16描述 ...

  5. 2017 Russian Code Cup (RCC 17), Final Round

    2017 Russian Code Cup (RCC 17), Final Round A Set Theory 思路:原题转换一下就是找一个b数组,使得b数组任意两个数的差值都和a数组任意两个数的差 ...

  6. hdoj4685

    数据: /*999993 43 1 2 42 2 32 3 4*/ #include <iostream> #include <cstdio> #include <cma ...

  7. You Dream. We Test.

      https://www.keysight.com/us/en/home.html https://www.ixiacom.com/ IXIA 被收,才发现她

  8. Git中修复bug

    问题描述:提交的远程分支中有一个小bug需要修复: 首先在本地拉取指定分支的代码: git checkout -b test origin/远程分支 git pull 再从test分支中切一个分支: ...

  9. 『TensorFlow』数据读取类_data.Dataset

    一.资料 参考原文: TensorFlow全新的数据读取方式:Dataset API入门教程 API接口简介: TensorFlow的数据集 二.背景 注意,在TensorFlow 1.3中,Data ...

  10. 数据结构与算法之PHP排序算法(希尔排序)

    一.基本思想 希尔排序算法是希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本. 该方法的基本思想是:先将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的)分别进行直接 ...