2013-03-11 84 views
2

我想與一個結構和一個uint64_t進行聯合,所以我可以引用單個uint16_ts與結構,並將它們串聯在uint64_t中。我在此測試程序:結構和整數的內存順序

#include "stdio.h" 
#include "stdint.h" 
struct test_struct{ 
    uint16_t stuff; 
    uint16_t a; 
    uint16_t b; 
    uint16_t c; 
}; 

union test_union{ 
    struct test_struct str; 
    uint64_t uint; 
};  

int main(){ 
    struct test_struct x = { 
     .stuff = 0x0000, 
     .a = 0x1234, 
     .b = 0x5678, 
     .c = 0x9ABC 
    }; 
    union test_union y; 
    y.str = x; 

    printf("y.uint: %llX\n", y.uint); 
} 

輸出成爲:

y.uint: 9ABC567812340000 

其是反直覺的,我(它是768,16 000ABC,或123456789ABC)。有人可以向我解釋爲什麼結構中的元素似乎被顛倒了嗎?

編輯: 供將來參考:字節順序的答案讓我感到困惑,因爲uint16_ts是按照正確的順序打印的。但是,這當然是因爲它們本身存儲的是小端。

回答

7

您處於一個小端平臺,首先存儲的字節(地址最低)結束於組合的uint64_t的最低有效位(右側打印時)。

如果你在一個big-endian平臺上運行相同的代碼,你會得到你期望的結果。現在的代碼不能在具有不同字節順序的系統上移植。

0

這一切都與Endianess。我不認爲C/C++語言定義了這種工作方式,而是將它留給實現/目標CPU來定義。在一個大端的CPU上,你會得到你所期望的。

0

如果你的處理器是「小端」,LSB存儲在最低地址,所以這是一個正常的輸出。在英特爾的x86平臺上,通常它是小端的。相比之下,摩托羅拉的PowerPC是大端,也就是說,MSB存儲在最低地址。