好的,所以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
对于所有五个函数调用都相同?
答案 0 :(得分:6)
&ptr
是相同的,因为ptr
是test()
中的局部变量。由于你连续五次调用test()
而没有任何干预,所以每次调用时都会在堆栈上给出相同的地址(注意,这不是 required 通过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()
进行的。