union的妙用

union的妙用

標籤(空格分隔): 文章git


做者github:smilesometimesgithub

1 union 介紹

徹底就是共用一個內存首地址,而且各類變量名均可以同時使用,操做也是共同生效。union的內存分配是按內存佔用最大的變量分配的。數組

2 判斷本機採用大端仍是小端表示法

//本機小端返回0大端返回1,
//intel cpu通常採用小端表示法,返回是0
static int get_endian()
{
    union
    {
        unsigned long int i;//32位long佔4位
        unsigned char s[4];
    }c;
    c.i = 0x12345678;      
   //在內存中佈局是這樣的,0x00DCFA94(c的地址 低-->高)78 56 34 12  
    return (0x12 == c.s[0]);
}

3 stl內存分配的free_lists節點結構

當時讀到書中的這個地方就以爲頗有意思,free_list_link 和 cliet_datta確實很巧妙。緩存

//節省內存開銷
union obj{
    union obj * free_list_link;
    char cliet_datta[1]; /*the client see this  */
}
//參考《stl源碼剖析》 第二章

關於這個問題,知乎討論連接https://www.zhihu.com/questio...網絡

4 表示ipv4地址

ip地址是32位bit,因此在unix中是用無符號整數表示。在看opendhcp的代碼時看見ip地址函數

//opendhcp ip地址定義
struct data15
{
    union        //MYDWORD ip;
    {
        unsigned ip:32;
        MYBYTE octate[4];
    };
};
//使用的時候
data15 inaddr;
inaddr.ip = ip;
//直接取數組進行操做有沒有很精妙哈
sprintf(target, "%u.%u.%u.%u", inaddr.octate[0], inaddr.octate[1], inaddr.octate[2], inaddr.octate[3]);

//unix ip地址的定義
struct in_addr{
    usigned int s_addr;/*network byte order(big endian) */
}

5 表示一些緩存

也是在opendhcp的代碼中好像看到過這種用法,不過沒看懂,回頭在研究。佈局

擴展信息

擴展介紹this

2.1 大端小端介紹(一個地址單元存一個byte)

小端表示法就是低地址存數字的高位,高地址存數字的低位。通俗的來講,就是小端法咱們從內存中看一個數的話(低->高),得反過來讀,大端法則從前日後讀就行。好比0x8049464這樣一個數(64是數字的低位),小端法的內存(低->高)是 64 94 04 08 ,而大端法的內存是 08 04 94 64。參考自《深刻理解計算機原理》第2章。spa

2.2 網絡字節序(大端表示法)

網絡上傳輸數據得忽略主機的差別,因此按照了統一的方式規定。 參考自《深刻理解計算機原理》第11章。unix

  • unnix 提供了四個轉換函數,htonl htons ntohl ntohs;

  • h: host表示主機, to:to 表示轉換, n:network(網絡), s:short 16位地址轉換, l:long 32位地址轉換;

  • 好比htons 表示16位主機順序到網絡順序的轉換。通常是經過宏定義交換字節位置實現。

短整型大小端互換
#define BIGLITTLESWAP16(A)   ((((unsigned short int)(A) & 0xff00) >> 8) | \
                             (((unsigned short int)(A) & 0x00ff) << 8))

2.3舉個栗子吧(哈哈)
來個wireshark的udp包哈哈,以下圖udp源端口號64361(udp協議規定2個byte表示端口號0 - 65535),在udp包中的內存就是0xfc77(16進制的64631),大端表示法直接讀就行.
wireshark.JPG-147.9kB

相關文章
相關標籤/搜索