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()。では、なぜ&ptr5 つの関数呼び出しすべてが同じなのでしょうか?

4

1 に答える 1

6

&ptrptrは内のローカル変数であるため、同じですtest()。何も介入せずに 5 回連続して呼び出しているためtest()、呼び出されるたびにスタック上で同じアドレスが与えられているだけです (注意してください、これはCでは決して必要ではありません。そして、それが通常どのように起こるか)。

2 番目の関数を呼び出し、それ自体が を呼び出した場合、以前に存在していたスタック上のスペースが介在する関数呼び出しによって使用されているtest()ため、 に対して同じ出力が得られません。&ptrptr

例えば:

#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 に答える