2016-03-21 77 views
0

這是我的代碼。結構內變量的地址計算

#include <stdio.h> 
#include <stdlib.h> 
#include <stdint.h> 

struct test 
{ 
    unsigned int x; 
    long int y: 32; 
    unsigned int z; 
}; 

int main() 
{ 
    struct test t; 
    unsigned int *ptr1 = &t.x; 
    unsigned int *ptr2 = &t.z; 
    printf("ptr1 address is %p\n", ptr1); 
    printf("ptr2 address is %p\n", ptr2); 
    printf("size: %d", ptr2 - ptr1); 
    return 0; 
} 

這是輸出:

ptr1 address is 0028FEDC 
ptr2 address is 0028FEE4 
size: 2 

我想我在這裏失去了一個點,我輸出的認識。我期待輸出爲4.因爲,long int在我的機器上佔用4個字節。我得到了x和z的地址之間的區別。但是,不是真實的輸出,而不是通過手動減去x和z的地址而獲得的輸出。如果你看到上面的內容,根據我的計算,28FEE4-28FEDC = 8,但輸出是2.誰能告訴我我的計算錯在哪裏?

+0

如果要在結構中使用32位有符號整數,爲什麼要使用位域而不是'int32_t'? –

+0

爲了得到字節數,你需要按指定類型的大小縮放指針的差別:'ptr2-ptr1' = 2,乘以'sizeof(unsigned int)',這顯然是4系統,得到8個字節。 – owacoder

+0

從技術上講,你對兩個指針的減法是* undefined behavior *,因爲它們都不指向「對象」。 –

回答

1

爲了解釋這一行爲,你可以看看你的結構是這樣的:

 
+---+---+---+ 
| x | y | z | 
+---+---+---+ 
^  ^
|  | 
&t.x &t.z 

&t.x&t.z之間的區別是元素,第一個從&t.x&t.y,再一個從&t.y&t.z

應該指出的是,這隻適用於只有因爲所有三種類型是相同的大小和編譯器沒有在結構中添加任何填充。

+0

看起來像我過分想到這個,因爲地址值,忘了按指針類型縮放它。謝謝! –

+0

並感謝您關於填充的說明。我甚至忘記了這一點。 –