對比結構體成員的值,uint16_t類型和uint32_t類型的成員值都相反:

可見在強制轉換的過程中,如果忽略了大小端問題,那么轉換的結果將會和預期的不一致,要么導致程序處理異常而跑飛,要么導致內存溢出而系統崩了!
數據收發
數據收發,如果以嵌入式外設串行接口進行通信,收發大多是逐字節進行的,這里如果需要傳輸一個uint16_t或者uint32_t類型的數據,也都是被逐字節發出,此時就存在大小端的先后問題了。
這一點與上個問題的數據包解析和組包其實是個逆過程,也就是把特定結構的數據,強制轉換為逐字節的數據流,從而在接口上逐字節被處理或者發出去。
構造一個結構體,對結構體各個成員進行賦值,然后將結構體對象傳給接口發出去,看看大小端平臺里的區別,Debug過程截圖如下:

用一個uint8_t類型的指針p3指向了結構體的首地址,也就是第一個成員的地址,p3 = &tmp_stru.val_u8;該語句把結構體的地址賦給了p3,緊接著調用傳輸接口時,接口的參數要求是uint8_t類型的指針,此時可以把p3作為參數傳入處理接口trans_port()。
繼續調試跟蹤傳輸接口內部取到的數據流情況:


觀察indata_tmp數組,依次被填入的數據是0x10,0x20,0x30,0x40,0x50,…可見uint16_t和uint32_t類型的數據被“拆分”時,高字節先被處理,例如0x2030的數據先處理0x20再處理0x30,再比如0x40506070的數據先處理0x40,最后處理0x50!這就是大端模式!
同樣的代碼,拿到小端模式的ARM平臺里運行,結果就完全不一樣了:


在ARM的小端平臺上,處理uint16_t和uint32_t類型的數據時,是反著來的!
綜合以上驗證,可以深刻理解和記憶嵌入式平臺開發時的大小端差異問題。平臺的大小端差異,不僅是數據存儲需要考慮,而且在讀取、使用和傳遞時,也需要多加留意,以免不必要的Bug產生。