6

好的,所以 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

1 回答 1

6

&ptr是相同的,因为ptr是 内的局部变量test()。由于您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;
}

产量:

paul@local:~/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

paul@local:~/src/c/scratch$

你可以看到&ptr在最后一次调用中有所不同,这是通过test_test().

于 2013-10-11T02:53:59.713 回答