曾經在學校學習C語言的時候一直搞不懂那個共用體union有什么用的。工作之后才發現它的一些妙用,現舉比例如以下:
1. 為了方便看懂代碼。
比方說想寫一個3 * 3的矩陣,能夠這樣寫:
[
注:以下用紅色部分標記的地方是后來加入上去的,謝謝yrqing718的提醒!
]
- struct ?Matrix
- {
- ???? union
- ????{
- ? ? ? ? struct
- ??????? {
- ??????????? float ?_f11,?_f12,?_f13,?_f21,?_f22,?_f23,?_f31,?_f32,?_f33;
- ??????? };
- ??????? float ?f[3][3];
- ????}_matrix;
- };
- struct ?Matrix?m;
這兩個東西共同使用同樣的空間,所以沒有空間浪費,在須要總體用矩陣的時候能夠用
m._matrix.f (比方說傳參,或者是總體賦值等);須要用當中的幾個元素的時候能夠用m._matrix._f11那樣能夠避免用m.f[0][0](這樣不大直觀,并且easy出錯)。
2. 用在強制類型轉換上(比強制類型轉換更加easy看懂)
以下舉幾個樣例:
(1). 推斷系統用的是big endian 還是 little endian(其定義大家能夠到網上查相關資料,此略)
- #define?TRUE?1
- #define?FALSE?0
- #define?BOOL?int
-
- BOOL ?isBigEndian()
- {
- ???? int ?i?=?1;??? /*?i?=?0x00000001*/
- ???? char ?c?=?*( char ?*)&i;? /*?注意不能寫成?char?c?=?(char)i;?*/
- ???? return ?( int )c !=?i;
- }
反之亦然
或許看起來不是非常清晰,以下來看一下這個:
- BOOL ?isBigEndian()
- {
- ???? union
- ????{
- ???????? int ?i;
- ???????? char ?c;
- ????}test;
- ????
- ????test.c?=?2;
- ?
- ???? return ?test.i?!=?2;
- }
這里用的是union來控制這個共享布局,有個知識點就是union里面的成員c和i都是從低地址開始對齊的。相同能夠得到如此結果,并且不用轉換,清晰一些。
什么,不認為清晰??那再看以下的樣例:
(2). 將little endian下的long long類型的值換成 big endian類型的值。已經知道系統提供了以下的api:long htonl(long lg);作用是把全部的字節序換成大端字節序。因此得出以下做法:
- long ? long ?htonLL( long ? long ?lg)
- {
- ???? union ?
- ????{
- ???????? struct ?
- ????????{?
- ???????????? long ?low;
- ???????????? long ?high;
- ????????}val_1;
- ???????? long ? long ?val_2;
- ????}val_arg,?val_ret;
- ???? if (?isBigEndian()?)
- ???????? return ?lg;
- ????val_arg.val_2?=?lg;
- ????val_ret.val_1.low?=?htonl(?val_arg.val_1.high?);
- ????val_ret.val_1.high?=?htonl(?val_arg.val_1.low?);????
- ??? return ?val_ret.val_2;
- }
僅僅要把內存結構的草圖畫出來就比較easy明確了。
(3).為了理解c++類的布局,再看以下一個樣例。有例如以下類:
- class ?Test
- {
- public :
- ???? float ?getFVal(){? return ?f;}
- private :
- ???? int ?i;
- ???? char ?c;
- ???? float ?f;
- };
- Test t;
不能在類Test中添加代碼,給對象中的f賦值7.0f.
- class ?Test_Cpy
- {
- ? public :
- ???? float ?getVal(){? return ?f;}
- ???? float ?setVal( float ?f){? this ->f?=?f;}
- private :
- ???? int ?i;
- ???? char ?c;
- ???? float ?f;
- };
- ....
- int ?main()
- {
- ????Test?t;
- ???? union
- ????{
- ?????????Test?t1,?
- ?????????Test_Cpy?t2;
- ????}test;
- ????test.t2.setVal(7.0f);
- ????t?= test.t1;
- ????assert(?t.getVal()?==?7.0f?);???
- ???? return ?0;
- }
說明:由于在添加類的成員函數時候,那個類的對象的布局基本不變。因此能夠寫一個與Test類一樣結構的類Test_Cpy,而多了一個成員函數setVal,再用uinon結構對齊,就能夠給私有變量賦值了。(這樣的方法在有虛機類和虛函數機制時可能失靈,故不可移植)至于具體的討論,網上有,這個樣例在實際中沒實用途,僅僅是用來考察這個內存布局的使用而已.
union在操作系統底層的代碼中用的比較多,由于它在內存共賞布局上方便且直觀。所以網絡編程,協議分析,內核代碼上有一些用到union都比較好懂,簡化了設計。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
