在内存位置使用双指针

问题描述

我试图了解这段代码中双指针的用途及其工作原理。

为什么我们在声明函数中使用 **p 而在函数内部使用 *p

void allocate(int** p)
{
  *p = (int*)malloc(sizeof(int));
}

int main()
{
  int *p = NULL;
  allocate(&p);
  *p = 42;
}

解决方法

函数的参数 p 具有指向 int 的指针类型,即 int **。因此,引用 p 是指该类型的对象。

表达式 *p dereferences p 给你一个类型为 int * 的表达式(也是一个 lvalue)。这与 p 函数中的 main 类型匹配,并且实际上是指该对象。这允许我们在函数 allocate 中修改 pmain 的值以包含动态分配的内存块的地址。

,

要更改在函数p 中的函数main 中声明的原始指针allocate,您需要通过引用传递它。否则函数将处理原始指针p的值的副本,更改副本不会影响存储在原始指针中的值。

在 C 中,通过引用传递意味着通过指向对象的指针间接传递对象。因此,取消引用指针,您将可以访问原始对象。

考虑以下演示程序。

#include <stdio.h>

void f( int x )
{
    x = 20;
}

int main(void) 
{
    int x = 10;
    
    printf( "Before calling the function d c = %d\n",x );
    
    f( x );
    
    printf( "After  calling the function d c = %d\n",x );

    return 0;
}

它的输出是

Before calling the function d c = 10
After  calling the function d c = 10

如您所见,原始变量 x 在调用函数 f 后没有改变,因为变量是按值传递给函数的。

现在考虑以下程序。

#include <stdio.h>

void f( int *px )
{
    *px = 20;
}

int main(void) 
{
    int x = 10;
    
    printf( "Before calling the function d c = %d\n",x );
    
    f( &x );
    
    printf( "After  calling the function d c = %d\n",x );

    return 0;
}

此时程序输出为

Before calling the function d c = 10
After  calling the function d c = 20

由于变量 x 是通过引用传递然后取消引用指针 px

*px = 20;

您可以通过指针直接访问原始变量 x

所以如果你想改变一个指针本身,那么通过引用传递它意味着传递一个指向该指针的指针,就像在上面的函数中所做的一样,只是现在原始变量p的类型是{ {1}} 而不是 int *

如果你有这样的声明

int

其中 T x; 是某种类型(例如 Tint),然后要通过引用传递变量,您需要使用函数参数表达式,如 int *。类型为 &x。如果 T * 等价于 T 类型,那么您需要使用 int * 类型的参数表达式。