被指针的内存交换困惑

时间:2014-09-21 23:30:43

标签: c pointers

函数swap2有两个参数int *aint *b。这些是指向整数值的指针。那么为什么当在swap2中执行诸如int tmp = *a; *a = *b;之类的行时,它会改变这些值的内存位置。 *不会参与参数中声明的指针吗?

int main()
{
        int x = 42;
        int y = 9;
        printf("x = %d, y = %d\n", x, y);
        swap1(x,y);
        printf("x = %d, y = %d\n", x, y);
        x = 42, y = 9;
        swap2(&x, &y);
        printf("x = %d, y = %d\n", x, y);
        printf("---\n");
        int z = 77, w = 33;
        int *p = &z;
        int *q = &w;

        printf("*p = %d, *q = %d, p = %p, q = %p\n", *p, *q, p, q);
        swap2(p,q);

        z = 77, w = 33;
        printf("*p = %d, *q = %d, p = %p, q = %p\n", *p, *q, p, q);
        swap3(&p, &q);
        printf("*p = %d, *q = %d, p = %p, q = %p\n", *p, *q, p, q);

        printf("z = %d, w = %d\n", z, w);

        return 0;
}

void swap1(int a, int b)
{
        int tmp = a;
        a = b;
        b = tmp,
        printf("a = %d, b = %d\n", a, b);
}

void swap2(int *a, int *b)
{
        int tmp = *a;
        *a = *b;
        *b = tmp;
        printf("*a = %d, *b = %d\n", *a, *b);
}

void swap3(int **a, int **b)
{
        int *tmp = *a;
        *a = *b;
        *b = tmp;
        printf("**a = %d, **b = %d\n", **a, **b);
}

1 个答案:

答案 0 :(得分:1)

更新

swap2 (int *a, int *b)不会更改任何内存位置,它会更改ab指向的内容,当您调用swap2(&x, &y)时,您的内存架构看起来像以下内容:

                             int x
[a (address of x)] ->  [actual x = 42]

                             int y
[b (address of y)] ->  [actual y = 9]

int tmp = * a;

[tmp = (deference address of x) = actual x = 42]

* a = * b;

                                        int x
[a (address of x)] ->  [deference b => actual y => 9]

* b = tmp;

                                    int y
[b (address of y)] ->  [tmp => actual x => 42]

由于swap3(int ** a, int **b)采用“指向int的指针”,a(和b)的内存模式如下所示:

                           int * p
[a (some address 1)] -> [another address A'] -> [real integer value A'']

                           int * q
[b (some address 2)] -> [another address B'] -> [real integer value B'']

因此,当你尊重a时,你实际上得到了[另一个地址],这就是为什么你实际上改变了内存位置而不是实际值。

当你执行int * tmp = * a时,由于你在右侧推荐一个,现在它的值将是“另一个地址A`”,内存架构将变为:

[tmp (another address A')] -> [real integer value A'']

执行* a = * b,你实际上是这样做的,注意a的值没有改变,你只改变它指向的内存:

                             int * p
[a (some address 1)] -> [another address B'] -> [real integer value B'']

最后,* b = tmp,还注意到b的值没有改变:

                             int * q
[b (some address 2)] -> [another address A'] -> [real integer value A'']