为什么基于指针交换两个值不能在函数范围之外工作?

Ant*_*ony 9 c++ swap pointers

我已经用C++编程好几年了,所以我决定用指针刷新我的记忆.

在两个数字之间交换的经典示例中,示例是

void swapPointersClassic(double *num1, double *num2) 
{
  double temp;
  temp = *num1;
  *num1 = *num2;
  *num2 = temp;
}
Run Code Online (Sandbox Code Playgroud)

这允许我们进行函数调用swapPointersClassic(&foo, &bar);,因为我们传入变量foo和bar的内存地址,函数将检索值并进行交换.但我开始怀疑,为什么我不能做以下事情呢?

void swapPointers(double *num1, double *num2)
{
  double *temp;
  temp = num1;
  num1 = num2;
  num2 = temp;
}
Run Code Online (Sandbox Code Playgroud)

这对我来说似乎更有意义,因为我们只需要创建足够的临时存储来存储内存地址num1(而不是用于存储双值*num1的完整临时存储).但是,似乎函数范围限制了指针交换的效果.在调用之后swapPointers(&foo, &bar);,我可以看到函数swapPointers中,foo和bar确实被交换了.一旦我们退出swapPointers函数,就不再交换foo和bar了.任何人都可以帮助我理解为什么会这样吗?这种行为让我想起了典型的pass by value方法,但是我们在这里通过指针.这意味着我们只能触摸那些指针指向的值,而不是指针本身?

小智 6

实际上你并没有真正通过指针.你按值传递两个指针.传递指针本身是不够的 - 你必须取消引用它们.解除引用(指针的副本)的行为使得魔术发生,并且它是实现范围遍历的实际位置.

修改函数的参数是函数的本地参数,即使参数本身是指针也是如此.你必须取消引用它们才能访问它们指向的内存(同样,"通过指针传递"不仅仅是传递指针 - 它传递指针正确使用它们).

另外,请考虑以下内容.如果您的第二种方法有效,并且两个指针被交换,则意味着交换变量地址.这没有多大意义.

顺便说一句,在C++中我们有一个真正的传递引用调用约定,所以 不需要乱用指针:

void swap(double &a, double &b)
{
    double temp = a;
    a = b;
    b = temp;
}

float a = 1, b = 2;
swap(a, b);
Run Code Online (Sandbox Code Playgroud)

(这只是一个实现问题,编译器很可能通过实际使用指针来实现这种行为,但至少你没有头疼.)

  • @CodingMash好吧,我从未认为它们是一场噩梦,它们是C和C++最好的基本功能之一. (3认同)

Ale*_*ato 5

如果要交换指针而不是它们的值,则需要传递指针指针:

void swapPointers(double** num1, double** num2)
{
  double* temp = *num1;
  *num1 = *num2;
  *num2 = temp;
}
Run Code Online (Sandbox Code Playgroud)

您可以在http://ideone.com/iklCta中看到一个示例

您甚至可以使用参考资料:

void swapPointers(double*& num1, double*& num2) {
  double* temp = num1;
  num1 = num2;
  num2 = temp;
}
Run Code Online (Sandbox Code Playgroud)

示例:http://ideone.com/w4k9mV

当您处理大型对象(例如:图像数据)并且您不想移动大量内存时,这很有用,但只需要引用.