2015-09-19 112 views
-4

我正在學習指針基礎知識。請看看我的示例代碼,並告訴我發生了什麼。C指針:解釋程序概念

void main() 
{ 
    int i, *j; 
    i = 2; 
    j = i; 
    printf("%d", j); 
    printf("\n%d", j + 1); 
    printf("\n%d", j + 2); 
} 

我的輸出

2 6 10 

請解釋我..

+2

你可能更適合自己閱讀這個主題。這個問題在過去幾乎被數千次**問過。 –

+1

「_tell我怎麼回事」 - 除了未定義的行爲。 –

+1

如果你增加一個指向一個整數的指針,它將以一個整數的大小遞增,所以它指向數組中的下一個整數。 – wimh

回答

5

您所看到的輸出是因爲你指定的地址0x02指針j當你寫j + 1你是通過遞增1與遞增其地址sizeof(int)sizeof(*j)相同。

但行爲實際上是不確定的是commented here最初由@Filipe Gonçalves,並回答my question - 由@Kninnug

C11 § 6.5.6/8 here

[.. ]如果指針操作數和結果指向相同數組對象的元素,或者指向數組對象的最後一個元素,則評估不應產生溢出;否則,行爲是不確定的。 [..]

你可以查看官方文檔閱讀更多關於它。

此外,您的printf()調用是未定義行爲的原因。您應該使用%p說明符打印指針,並將指針指向void *,如果您希望賦值正確,則還應將該地址轉換爲int *以使其工作。

如果您的系統是64位,那麼將i複製到(int *)也可能不夠。如果你曾經提領j

j = i; 

可能會導致不確定的行爲。

你應該的整數分配給這樣,也許你的意思

j = &i; 
與編譯警告

否則啓用,編譯器應該警告你不正確的任務,雖然它是有效的它不正確指針。


注意main()回報int,並已申報/它定義爲沒有返回值。

+0

'j + 1'和'j + 2'是UB。只有當結果指針指向同一個數組中的一個元素或者結束時的一個位置時,指針運算才能很好地定義。使用'%d'修飾符打印'j'也是UB。 –

+0

@FilipeGonçalves你確定嗎?你能告訴我標準的哪一部分是提到的,所以我可以修復答案嗎?我以爲它是無效的,但是在我看來,它並不一定,除非你解除指針的引用。 –

+2

@iharobC11§6.5.6/ 8:[*] *如果指針操作數和結果指向同一個數組對象的元素,或者一個超過數組對象的最後一個元素,那麼評估將不會產生溢出;否則,行爲是不確定的。* [..] – Kninnug