2013-10-11 51 views
6

好吧,所以C是按值傳遞的,這意味着使用變量的副本而不是參數的原始變量,對吧?那麼,這個副本是否總是有相同的內存地址?考慮以下代碼:C中的函數參數是否總是具有相同的內存地址?

void test(int *ptr) { 
    printf("&ptr: %p\n", &ptr); 
    printf("ptr: %p\n", ptr); 
    printf("*ptr: %d\n\n", *ptr); 
} 

int main() { 
    int a = 1, b = 2, c = 3, d = 4, e = 5; 
    test(&a); 
    test(&b); 
    test(&c); 
    test(&d); 
    test(&e); 

    return 0; 
} 

輸出我從這個代碼得到是這樣的:

&ptr: 0x7fff70536728 
ptr: 0x7fff7053674c 
*ptr: 1 

&ptr: 0x7fff70536728 
ptr: 0x7fff70536750 
*ptr: 2 

&ptr: 0x7fff70536728 
ptr: 0x7fff70536754 
*ptr: 3 

&ptr: 0x7fff70536728 
ptr: 0x7fff70536758 
*ptr: 4 

&ptr: 0x7fff70536728 
ptr: 0x7fff7053675c 
*ptr: 5 

我的直覺是「不」。我的理解是ptr不存在test()代碼塊之外。那麼,爲什麼&ptr對於所有五個函數調用都是相同的?

+4

它不保證是相同的。你正在觀察未指定的行爲。 (如果您使用除main之外的其他函數調用地址,則可以看到地址更改。) –

+0

即使沒有中間函數調用,它也可能不會顯示此行爲。取決於特定機器上的實現。 –

+0

@AndyzSmith也取決於編譯器如何決定實現它。 :) – jmstoker

回答

6

&ptr是相同的,因爲ptrtest()內的局部變量。既然你連續五次調用test()而沒有任何干預,它每次被調用時都會被賦予相同的地址(注意,這不是以任何方式必需的 C - 它只是你的機器是如何這樣做,以及它通常會如何發生)。

如果你打電話,然後自己稱爲test()第二功能,你不會得到相同的輸出&ptr,因爲其中ptr以前居住,現在正在使用的干預函數調用堆棧上的空間。

例如:

#include <stdio.h> 

void test(int *ptr) { 
    printf("&ptr: %p\n", (void *) &ptr); 
    printf("ptr: %p\n", (void *) ptr); 
    printf("*ptr: %d\n\n", *ptr); 
} 

void test_test(void) { 
    int a = 1; 
    test(&a); 
} 

int main() { 
    int a = 1, b = 2, c = 3, d = 4, e = 5; 

    test(&a); 
    test(&b); 
    test(&c); 
    test(&d); 
    test(&e); 
    test_test(); 

    return 0; 
} 

產量:

[email protected]:~/src/c/scratch$ ./ptrtest 
&ptr: 0x7fff39f79068 
ptr: 0x7fff39f7909c 
*ptr: 1 

&ptr: 0x7fff39f79068 
ptr: 0x7fff39f79098 
*ptr: 2 

&ptr: 0x7fff39f79068 
ptr: 0x7fff39f79094 
*ptr: 3 

&ptr: 0x7fff39f79068 
ptr: 0x7fff39f79090 
*ptr: 4 

&ptr: 0x7fff39f79068 
ptr: 0x7fff39f7908c 
*ptr: 5 

&ptr: 0x7fff39f79048 
ptr: 0x7fff39f7906c 
*ptr: 1 

[email protected]:~/src/c/scratch$ 

,你可以看到,&ptr是在最後一次通話,這是通過test_test()不同。

+0

好吧,現在有道理,謝謝! – instagatorTheCheese

相關問題