【问题标题】:Using Double Pointers in Memory Location [duplicate]在内存位置中使用双指针 [重复]
【发布时间】:2021-06-29 11:44:52
【问题描述】:

我正在尝试理解此代码中的目的以及它是如何工作的双指针。

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

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

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

【问题讨论】:

  • **p是指向指针的指针,所以*p是指向p的指针
  • int ** 是“指向 int 的指针”。 double * 是一个双指针。
  • int** 在概念上与int* 相同,只是它所持有的地址是int* 而不是int。如果您在到处删除一级指针后理解该示例,那么理解该示例是相同的过程。如果您不理解更简单的版本,我建议您改为学习。

标签: c pointers pass-by-reference function-declaration function-parameter


【解决方案1】:

要更改函数main 在函数allocate 中声明的原始指针p,您需要通过引用传递它。否则该函数将处理原始指针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

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

现在考虑以下程序。

#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 的类型是 int *而不是int

如果你有这样的声明

T x;

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

【讨论】:

    【解决方案2】:

    函数的参数p具有指向int的指针类型,即int **。所以引用p 指的是那个类型的对象。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-03-23
      • 2013-03-31
      • 1970-01-01
      • 2016-12-13
      • 2021-10-20
      • 1970-01-01
      • 2013-11-30
      相关资源
      最近更新 更多