c# 如何 使用共用體

來源:互聯網
上載者:User

標籤:col   原理   font   上傳   c#   支援   .text   實現   輸入   

用起來真的方便 轉摘如下:

C#藉助FieldOffset屬性實現共用體與強制類型轉換

     這兩天被C#的強制類型轉換弄得有點不習慣。事出如此。

     在C#中,我打算讀二進位文。檔案的結構很簡單,一連串的緊密儲存的int32值,以二進位方式存放。現在我希望隨機讀取第n個int32開始的i個值,並讀入到數組中。結果查一下C#只能讀到byte[]中,要不就是一個個讀出來迴圈放int[]。追求效率的我當然不希望這樣,如果能像C++那樣將byte[]強制轉換成int[]就好了。例如:

 

[cpp] view plain copy  print?
  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#中無法直接實現,為此我想了好些辦法,也查了好久,直到我見到了這樣的代碼:

 

[csharp] view plain copy  print?
  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.   
  9. namespace test  
  10. {  
  11.     class Program  
  12.     {  
  13.         // StructLayout使設計者可以控制類或結構的資料欄位的物理布局  
  14.         // Explicit與FieldOffset一起可以控制每個資料成員的精確位置  
  15.         [StructLayout(LayoutKind.Explicit)]  
  16.         public struct S1  
  17.         {  
  18.             // FieldOffset控制欄位所在的物理位置位移為0  
  19.             [FieldOffset(0)]  
  20.             public byte[] a;  
  21.             // 同樣位移為0,開始位置與a重疊了。  
  22.             [FieldOffset(0)]  
  23.             public int[] b;  
  24.         }  
  25.   
  26.         static void Main(string[] args)  
  27.         {  
  28.             S1 s = new S1(); // 要new,不然b會報“使用了可能未賦值的欄位”  
  29.             s.a=new byte[64];  
  30.   
  31.             FileStream FS = new FileStream("E:\\test.txt", FileMode.Open);  
  32.             // 以s.a來接收檔案的資料  
  33.             FS.Read(s.a,0,64);  
  34.   
  35.             // 自己保證讀b的時候不要越界  
  36.             for (int i = 0; i < 16; i++)   
  37.                 Console.Write(s.b[i]+" "); // 以b來使用資料  
  38.   
  39.             Console.ReadKey();  
  40.         }  
  41.     }  
  42. }  

 

原理實際上跟C++一樣,將一個int[]型的變數指向與byte[]型變數相同的記憶體地區,跟C++中將dat指向char數組的首地址是一樣的。同樣,這樣的結構體功能與C++的共用體是一樣的,即一個結構可以作為多種資料類型,而具體是什麼類型視情況而定。

測試所使用的檔案就不上傳了,有WinHex的可以自己編輯一個,沒有的也可以寫程式將從0xF到0x0的16個數以二進位方式輸出到檔案中。檔案的內容用WinHex開啟以16進位顯示應該如下:

c# 如何 使用共用體

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.