国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

.Net冷知識之UInt32轉換為Byte的方法1、2、3

2019-11-17 03:18:56
字體:
來源:轉載
供稿:網友

.Net冷知識之UInt32轉換為Byte的方法1、2、3

老天爺你算是贏了,忽冷忽熱的搞毛啊。最近因為各種原因掌握了豐富的就診經驗(好吧,和這篇博文一樣毫無意義的技能Get★daze)。

本來這篇博文的內容是上周沖澡的時候腦洞大開的成果,結果由于各(lan)種(de)原(dong)因(shou)拖延到了今天,那就順手當作三八婦女節獻禮好了(<ゝω?)綺羅星☆。

今天要討論的是有多少種無趣的手段把一個UInt32拆成4個Byte。至于其他長度整形的拆解就請自行舉一反三吧。

首先,肯定是第一個想到的,就是進行位運算。沒什么好說的,關門放代碼:

byte p1=(byte)(ipt >> 24);byte p2=(byte)(ipt >> 16);byte p3=(byte)(ipt >> 8);byte p4=(byte)(ipt);

上述代碼通過位移分別從高到低取得4個byte,簡單實用。通常這種方法就完全夠用了(唯一的問題就是需要口算位移……好煩)。但是標題都劇透了1、2、3,這時候放棄博文就結束了。那么,乘我還沒被凍死就進入方法2吧。

方法2的想法倒是很直接:既然一個UInt32在內存中分配了4個字節的長度,為何我們不直接訪問這4個字節呢?就像吐司面包一樣,直接平分4片就是了。

為了平分一個UInt32,就要直接操作內存。C#中除了幾個特殊的地方,平常沒有人需要用到指針這玩意。不過既然玩的就是腦洞打開,還是果斷祭出許久沒見到的指針吧:

byte* p = (byte*)&ipt;byte p1=p[3];byte p2=p[2];byte p3=p[1];byte p4=p[0];

由于X86平臺上采用的是Little Ending布局,所以這里內存訪問的順序是和直覺相反的(好吧,其實內存布局問題早忘了,要不是看到結果反了也不會順手查了下WIKI)。小細節不要那么在意啦,還是速度說下下一種吧。

方法3其實應該算是方法2的變種。既然用指針能訪問每個byte,那除了指針外還有什么方法也能達到同樣效果呢?

C里面有個叫共用體(union)的特殊類型,此類型的神奇效果是其字段共用一個內存位置,也就是說一個UInt32在內存中是可以和4個Byte重疊在一起的。如果我們可以用這種方法的話,不就意味著可以直接讀到分割的結果了么?那么,唯一的問題是共用體在C#中沒見過啊?沒有一個類型叫union的玩意?

其實,這玩意是存在的。只是除了P/Invoke調用以外實在太無存在干了。其實就是通過StructLayoutAttribute指定手動內存布局,并通過FieldOffsetAttribute手動將內存布局重疊到一起。代碼如下:

[StructLayout(LayoutKind.Explicit)]internal struct UIntByteConverter{    [FieldOffset(0)]    public uint Source;    [FieldOffset(0)]    public byte part4;    [FieldOffset(1)]    public byte part3;    [FieldOffset(2)]    public byte part2;    [FieldOffset(3)]    public byte part1;}

然后接下來的事情就簡單了,也就是對Source賦值完直接讀取結果罷了。

那么,本篇博文就這么結束了。有沒有覺得什么東西怪怪的?

有么?

沒有么?

有么?

這是湊字數么?

這不是湊字數么?

……

……

……

……

好吧,其實從標題開始我就沒說過只有三種方法嘛。至少還有種方法我是見別人有這么用過(不過對一個不太水的程序員來說,應該是毫無意義的方法來著)。

方法0(對,我就是喜歡從零數起,你咬我啊):轉成字符串然后拆分字符串再轉回來。

一看就知道效率很低,而且其實寫起來也很麻煩……

var temp=ipt.ToString("X8");byte p1=byte.Parse(temp.Substring(0, 2), NumberStyles.HexNumber);byte p2=byte.Parse(temp.Substring(2, 2), NumberStyles.HexNumber);byte p3=byte.Parse(temp.Substring(4, 2), NumberStyles.HexNumber);byte p4=byte.Parse(temp.Substring(6, 2), NumberStyles.HexNumber);

那么,以上方法的效率如何呢?說實話除了方法3要多一個對象創建而方法0完全坑爹外差別好小。對一個沒停藥的人來說方法1完全夠了(不過我總覺得某些方面方法3也有奇效)。具體如何請自行下載代碼自行跑測試吧。

代碼點我下載


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 清远市| 新绛县| 青海省| 新巴尔虎左旗| 西和县| 都安| 台中县| 格尔木市| 若羌县| 三原县| 怀来县| 晋州市| 永宁县| 襄樊市| 西乌珠穆沁旗| 沙河市| 横峰县| 左云县| 泽库县| 邯郸县| 谷城县| 大悟县| 中方县| 醴陵市| 海兴县| 广宗县| 阜新| 三穗县| 始兴县| 荆州市| 南汇区| 山西省| 和政县| 株洲县| 乌恰县| 邯郸市| 类乌齐县| 大城县| 白银市| 阳曲县| 江达县|