在c++中何时将指针指向指针作为参数传递给函数

When to pass a pointer to pointer as argument to functions in C++?

本文关键字:指针 参数传递 函数 c++ 何时      更新时间:2023-10-16

这里我读了一篇关于何时将指针作为函数参数传递的文章。但我想知道一些情况下,你应该传递一个指针到指针作为一个函数的参数。为了更清楚,我想知道什么时候应该使用这样的东西:

func(int **x);
void SomeFun1(int *);
void SomeFun2(int **);
int i;
int *ptr = &i;
//when you want value of ptr should remain unchanged, but you want to change only value of i, use,
SomeFun1(int *)
//when you want value of ptr should change. i.e, it should point to some other memory other than i, use,
SomeFun2(int **);

c++

在c++中,你可以通过引用传递,当你想修改形参来影响调用者传入的实参时,你可以这样做。也就是说,通过引用传递表示一个out或in/out形参。

如果函数需要一个指针(很明显),或者如果你想表示一个可选的输出参数,你可以传递一个指针——因为引用总是必须绑定到某个东西,但指针可以为空。

按照同样的逻辑,如果函数实际上需要双指针(在c++中非常罕见),或者如果你想表示指针类型的可选[in-]out形参(也非常罕见),则传递一个指针到指针。

下面是一些例子(人为的,但应该说明的事情):

int square(int x)  //pass int by value
{ return x * x; }
void squareRoots(double in, double &plus, double &minus)  //pass double by reference
{
  plus = sqrt(in);
  minus = -plus;
}
int toNumber(String s, bool *ok = nullptr)  //optional out parameter
{
  try {
    int val = s.toNumber();
    if (ok)
      *ok = true;
    return val;
  } catch (NotANumber &) {
    if (ok)
      *ok = false;
    return 0;
  }
}
int computeAge(Person *person)  //pass pointer by value
{
  if (!person)
    return -1;
  else
    return now() - person->dateOfBirth();
}
bool createPerson(Person * &person)  //pass pointer by reference
{
  if (tooManyPeople())
    return false;
  person = new Person();
  return true;
}
int sum(int **values)  //pass double pointer by value
{
  if (!values)
    return 0;
  int res = 0;
  while (*values) {
    res += **values;
    ++values;
  }
  return res;
}
bool allocate(int ** &arr)  //pass double pointer by reference
{
  if (!enoughMemory())
    return false;
  arr = new int*[1024];  // array of 1024 pointers to int
  return true;
}
bool newNode(Node **node = nullptr)  //optional out parameter
{
  Node *added = dataStructure.createNode();
  if (node)
    *node = added;
  return added;
}

(注1:我在这里只讨论非const引用,因为这与指针传递和引用传递有关。通过const-reference传递通常意味着"对象太大,无法进行不必要的复制",当指针指向指针时并不适用)。

(注2:上面的例子是可怕的,因为他们使用拥有原始指针,动态数组分配等。在实际的c++中,你可以使用智能指针,std::vector等。这就是为什么在c++中很少使用指针指向指针的原因)。


<标题> C 在C中,双指针更常见,因为C没有引用类型。因此,还可以使用指针"按引用传递"。在上面的c++示例中,&用于参数类型,而*将在C中使用(并且在操作参数时解引用)。一个例子:
void squareRoots(double in, double *plus, double *minus)  //pass double "by reference"
{
  *plus = sqrt(in);
  *minus = -*plus;
}

当您希望函数设置指针的值时,可以将一个指针传递给另一个指针作为参数。

当函数想要分配内存(通过malloc或new)并在参数中设置该值时,您通常会这样做——然后调用者将负责释放它。它比将其作为函数返回值返回要好,因为调用者不可能错误地忽略返回值并因不释放返回值而导致泄漏。

如果要返回多个值,也可能需要使用此方法。

这样做的另一个原因是当你想要可选地返回值(即指针指向指针可以为NULL)。例如,看看strtol(),它有一个可选的endptr。

  • 当你想传递一个指针数组时,你可以使用<type>**

的例子:

int main(int argc, char **argv) {   // argv is an array of char*

  • 如果你想改变指针地址,你也可以使用它(在c++中,你可以传递一个指针引用来代替这种情况)。

还没有提到的是动态分配二维数组——本质上,你会有一个指针数组指向其他指针。

这可能是我的观点。但是,当您希望使用NULL作为完美值时,例如,在链表中,指针应该用于变量。当您不希望将值初始化为NULL时,应该使用引用。否则,引用和指针在许多方面是相似的。可以在函数内部更改指针或引用形参的值。它们都是多态的. ...