C語言union用於打包和拆包資料

2022-02-04 03:44:44 字數 2939 閱讀 5169

union ;

} u1;

複製**

此union內部有兩個成員:第乙個成員「 word」是乙個兩位元組的變數。第二個成員是兩個單位元組變數的結構。為聯合分配的兩個位元組在其兩個成員之間共享。

分配的記憶體空間可以如下圖1所示。

圖1「 word」變數是指整個分配的記憶體空間,「 byte1」和「 byte2」變數是指構成「 word」變數的一位元組區域。我們如何使用此功能?假設您有兩個單位元組變數「 x」和「 y」,應將其組合以產生單個兩位元組變數。

在這種情況下,您可以使用上述聯合並為結構成員分配「 x」和「 y」,如下所示:

u1.byte1 = y;

u1.byte2 = x;

複製**

現在,我們可以讀取並集的「 word」成員,以獲得由「 x」和「 y」變數組成的兩位元組變數(參見圖2)。

圖2上面的示例顯示了使用並集將兩個乙個位元組的變數打包為單個兩個位元組的變數。我們也可以做相反的事情:將兩個位元組的值寫入「 word」,然後通過讀取「 x」和「 y」變數將其解壓縮為兩個乙個位元組的變數。將值寫入工會的乙個成員並讀取工會的另乙個成員有時被稱為「資料修剪」。

處理器位元組序

當使用聯合對資料進行打包時,我們需要注意處理器的位元組順序。正如羅伯特·基姆(robert keim)關於位元組序的文章所討論的那樣,該術語指定了資料物件的位元組在記憶體中儲存的順序。處理器可以是小端或大端。使用big-endian處理器時,資料的儲存方式是,包含最高有效位的位元組具有最低的記憶體位址。在小端系統中,包含最低有效位的位元組首先儲存。

圖3中所示的示例說明了序列0x01020304的小端和大端儲存。

圖3.由iar提供。

#include

#include

int main()

;uint16_t    word;

} u1;

u1.byte1 = 0x21;

u1.byte2 = 0x43;

printf("word is: %#x", u1.word);

return 0;

}複製**

執行此**,我得到以下輸出:

詞是:0x4321

這表明共享儲存空間的第乙個位元組(「 u1.byte1」)用於儲存「 word」變數的最低有效位元組(0x21)。換句話說,我用來執行**的處理器是little endian。

如您所見,聯合的特定應用程式可能表現出與實現有關的行為。但是,這不是乙個嚴重的問題,因為對於這樣的低階編碼,我們通常知道處理器的位元組序。如果我們不知道這些細節,我們可以使用上面的**來查詢資料在記憶體中的組織方式。

替代解決方案

除了使用並集,我們還可以使用按位運算子來執行資料打包或拆包。例如,我們可以使用以下**來組合兩個乙個位元組的變數「 byte3」和「 byte4」,並產生乙個單個的兩個位元組的變數(「 word2」):

word2 = (((uint16_t)   byte3) << 8 ) | ((uint16_t)   byte4);

複製**

讓我們比較一下小端和大端兩種情況下這兩種解決方案的輸出。考慮下面的**:

#include

#include

int main()

;uint16_t    word1;

} u1;

u1.byte1 = 0x21;

u1.byte2 = 0x43;

printf("word1 is: %#x\n", u1.word1);

uint8_t       byte3, byte4;

uint16_t      word2;

byte3 = 0x21;

byte4 = 0x43;

word2 = (((uint16_t) byte3) << 8 ) | ((uint16_t) byte4);

printf("word2 is: %#x \n", word2);

return 0;

}複製**

union ;

} u1;

複製**

#include

#include

int main();};

union buffer buff_tx;

union buffer buff_rx;

buff_tx.f = f1;

buff_rx.byte[0] = buff_tx.byte[0];

buff_rx.byte[1] = buff_tx.byte[1];

buff_rx.byte[2] = buff_tx.byte[2];

buff_rx.byte[3] = buff_tx.byte[3];

printf("the received data is: %f", buff_rx.f);

return 0;

}複製**

下面的圖4展示了所討論的技術。請注意,位元組是順序傳輸的。

圖4結論

聯合的原始應用程式建立了互斥變數的共享儲存區,但隨著時間的流逝,程式設計師已經廣泛使用聯合用於完全不同的應用程式:使用聯合進行資料打包/拆包。工會的這種特殊應用涉及將值寫入工會的乙個成員並讀取工會的另乙個成員。

「資料修剪」或使用聯合進行資料打包/拆包可能導致依賴於硬體的行為。但是,它具有更具可讀性和可維護性的優點。這就是為什麼許多程式設計師更喜歡在該應用程式中使用聯合的原因。當我們有任意大小的資料物件應通過序列通訊鏈結時,「資料修剪」將特別有用。

C語言union用於打包和拆包資料

使用union來打包 拆包資料union u1 複製 此union內部有兩個成員 第乙個成員 word 是乙個兩位元組的變數。第二個成員是兩個單位元組變數的結構。為聯合分配的兩個位元組在其兩個成員之間共享。分配的記憶體空間可以如下圖1所示。圖1 word 變數是指整個分配的記憶體空間,byte1 和...

C語言之struct和union分析

1.struct的小秘密 c語言中的struct可以看做變數的集合 struct的問題 空結構體占用多大記憶體?相關測試 include struct ts int main 實驗結果 以上結果是執行在gcc編譯器,如果使用bcc編譯器,則結果不同,此問題屬於c語言中灰色地帶 2.結構體與柔性陣列 ...

c語言的union和大小端模式

在c語言中允許不同型別的資料使用同一段記憶體,也就是不容型別的變數存放起始位址相同的記憶體中,雖然他們占用的位元組數可能不同,但是起始位址相同。共用體就是這樣的型別,它採用的是覆蓋儲存技術,允許不同型別資料互相覆蓋,共享同一段記憶體。如下 include union x void main 雖然,沒...