2013-10-11 46 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

相关问题