int cTest = 2; // 0x00000002
i2c_write(..., (unsigned char *)&cTest, ...);
小端模式:cTest 內存佈局 02 00 00 00,取地址 &cTest 指向最低位 0x02,正確傳遞寄存器地址 2。
大端模式:cTest 內存佈局 00 00 00 02,&cTest 指向最高位 0x00,錯誤傳遞寄存器地址 0!
C 標準規定:(unsigned char *)&cTest 取得的是變量的起始地址(最低地址)。大小端決定了數值在內存中的字節序,導致同一數值的起始字節內容不同。
// 明確定義參數類型,避免強制轉換
unsigned char regAddr = 2;
i2c_write(..., ®Addr, ...);
或使用聯合體/位操作顯式構造字節序。
char 是否帶符號由編譯器決定,顯式聲明 signed char/unsigned charhtonl/ntohl 等統一為大端網絡序__attribute__((packed, scalar_storage_order("big-endian"))) 控制結構體佈局-Wconversion -Wsign-conversionstatic_assert(CHAR_BIT == 8, "...")「平常寫代碼太過隨意,也不管什麼平台,也不注意參數類型。」大小端問題本質是對內存佈局假設與硬件實際不符。養成嚴格類型、顯式序列化的習慣,才能寫出可移植的健壯代碼。