2011-04-10 86 views
38

指針的值是變量的地址。爲什麼int pointer的值在int指針增加1後增加了4個字節。爲什麼int指針'++'增加4而不是1?

在我看來,我認爲指針增量後指針(地址變量)的值只增加1個字節。

測試代碼:

int a = 1, *ptr; 
ptr = &a; 
printf("0x%X\n", ptr); 
ptr++; 
printf("0x%X\n", ptr); 

預期輸出:

0xBF8D63B8 
0xBF8D63B9 

實際輸出:

0xBF8D63B8 
0xBF8D63BC 

編輯

的其他問題 - 如何訪問4個字節一個int佔用一個接一個?

回答

92

當您增加T*時,它將移動sizeof(T)字節。 這是因爲移動任何其他值沒有意義:例如,如果我指向的大小爲4個字節的int,例如,小於4的增量會使我處於什麼狀態?部分int與其他一些數據混合:無意義。


在內存試想一下:

[↓  ] 
[...|0 1 2 3|0 1 2 3|...] 
[...|int |int |...] 

當我增加該指針哪個更有意義?這:

  [↓  ] 
[...|0 1 2 3|0 1 2 3|...] 
[...|int |int |...] 

或者這樣:

 [↓  ] 
[...|0 1 2 3|0 1 2 3|...] 
[...|int |int |...] 

最後並沒有實際指向的任何形式的int。 (從技術上講,然後,使用指針UB

如果你真的要移動一個字節,遞增char*:的char大小始終是一個:

int i = 0; 
int* p = &i; 

char* c = (char*)p; 
char x = c[1]; // one byte into an int 

†這個推論是,您不能增加void*,因爲void是不完整的類型。

+0

「你不能增加'void *',因爲'void'是一個不完整的類型」 - true,但是gcc支持'void *'上的算術作爲擴展(它把它看作是'char *')。 – 2016-01-13 18:57:07

+0

「它對於一個整數幾乎總是沒有意義」,但對於像可變長度結構數組這樣的情況來說它是非常有意義的(「我有一個緩衝區充滿了數據包,我想將CurrentPacketPointer移動到下一個包」)。 – 2016-08-15 03:05:54

+0

「如果你真的想移動一個字節,增加一個char *:char的大小總是爲1」不,它不總是一個,你應該使用'uint8_t'來代替。 – Winter 2017-07-17 16:11:07

8

指針增量基於指向的類型的大小。如果int是4個字節,遞增1的int *如果一個短爲2個字節由4.

將增加它的價值,增加短* 1將由2.

這是增加其值C指針算術的標準行爲。

+0

我想他是在尋求理由。 – GManNickG 2011-04-10 07:20:40

+0

希望很明顯,基本原理是指針算術總是以指針對象的大小爲單位進行工作。 – 2011-04-10 07:23:20

+0

理由是*爲什麼*就是這種情況。 – GManNickG 2011-04-10 07:25:06

1

這個想法是,增加後,指針指向內存中的下一個int。由於整數是4個字節寬,所以它增加了4個字節。通常,指向類型T的指針將按sizeof(T)遞增

1

如您所說,int pointer指向int。一個int通常佔用4個字節,因此,當你增加指針時,它指向存儲器中的「下一個」int - 即增加4個字節。它適用於任何類型的任何尺寸。如果你有一個指向A的指針,然後增加一個A*它將增加sizeof(A)

想一想 - 如果你只增加一個字節的指針,它會指向一個int的中間,我不能想到這是一個需要的機會。例如,當迭代數組時,這種行爲非常舒服。

2

指針是增加了它們指向的類型的大小,如果指針指向炭,pointer++將遞增1指針,如果它指向一個1234個字節結構,pointer++將由1234

遞增指針

這可能會讓你第一次遇到它就感到困惑,但實際上它有很大的意義,這不是一個特殊的處理器特性,但編譯器會在編譯過程中計算它,所以當你編寫pointer+1時,編譯器將它編譯爲pointer + sizeof(*pointer)

相關問題