对指针的内存交换感到困惑

标签 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);
}

最佳答案

更新

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,现在它的值将是“另一个地址 A`”,内存模式将变成:

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

execute *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'']

关于对指针的内存交换感到困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25964931/

相关文章:

c - 如何使用 OpenSSL 生成 ECDHE 公钥?

Linux 中的共享中断线可以有不同的中断处理程序吗?

c - 使用字段元素初始化指向结构的指针

c++ - c_str使用不当

pointers - 对相同数据和内存分配的引用

c++ - 指针上的指针 - 性能损失的原因

c++ - 为什么在 Solaris 上生成的调用堆栈中的函数总是显示 6 个参数?

c++ - Opengl-es 2.0中渲染三角形的问题

c - 在 C 中解析 HTML 文件 - libxml2 的替代方案

c++ 使用 *& 作为参数(指针乐趣,三级树方法)