【问题标题】:Can someone explain what purpose passing by pointer and passing by reference have in c++?有人可以解释在 C++ 中通过指针传递和通过引用传递的目的是什么吗?
【发布时间】:2019-12-15 07:49:33
【问题描述】:

我只是不明白为什么要使用它们而不是变量。

例如,有人可以解释为什么这不起作用:

void swap(int x, int y) {
  int z = x;
  x = y;
  y = z;
}

int main() {
  int x, y;
  x = 5, y = 4;
  swap(x, y);
  cout << x << " " << y;
}

但这确实:

void swap(int *x, int *y) {
  int z = *x;
  *x = *y;
  *y = z;
}

int main() {
  int x, y;
  x = 5, y = 4;
  swap(&x, &y);
  cout << x << " " << y;
}

【问题讨论】:

    标签: c++ pointers reference


    【解决方案1】:

    在您给您的第一个示例中,您通过值传递参数,这会在内存中创建变量的副本,并且函数对副本进行操作。这意味着 x 和 y 的原始值不会被修改,只有它们的副本会被修改。当函数结束时,副本被销毁,原始值保持不变。

    在第二个示例中,您传入一个指针,该指针只是“指向”存储变量 x 和 y 的内存。当您取消引用(* 运算符)指针时,您可以像使用其他任何变量一样使用该变量,这意味着这样做:

    *x = *y;
    

    您实际上是将内存地址 x 处的变量设置为内存地址 y 处变量的值。与第一个代码 sn-p 不同,这会全局更改变量的值。

    简而言之,按值传递会创建 x 的副本供您使用。函数完成后 x 被销毁,原始 x 变量保持不变。通过指针或引用传递意味着您传入 x 的存储位置,然后访问 x 变量。当函数结束时,x 仍然被修改。

    它们为什么存在?
    简而言之,将指针传递给大型对象很有用,因为创建具有大量内存占用的类或结构的副本真的很慢。

    什么时候应该传值
    当您只想要数据的副本而不修改原始数据时,通常是因为修改原始数据是不必要的或对应用程序有害。

    什么时候应该通过引用传递
    当你想修改函数内变量的原始值时。

    什么时候应该使用指针?
    当您想修改内存中的变量或为该内存地址分配一个全新的变量时。

    【讨论】:

      【解决方案2】:

      我将分两部分回答这个问题。

      首先,为什么这两对代码的行为不同。这很简单。当您调用函数并通过引用传递或使用指针时,该函数正在查看变量的内存位置,然后修改这些内存位置的内容。因此,当您对变量(或交换变量)进行更改时,该更改将在函数调用之外可见。

      在第一组代码中,您传递给函数的 int 值实际上被复制到仅在函数内部定义的新临时变量中。所以该函数使用相同的数字,但是当它修改它们时,修改只针对那些复制的变量,而不是原始变量。

      那么,为什么要通过引用传递。我通常在我的代码中通过引用传递的主要原因是它更快。如果你将一个大对象传递给一个函数,你不想复制所有的数据。 (当然,对于大多数代码而言,这种速度可能可以忽略不计,但节省时间并没有什么坏处。)您关心的另一个原因是,正如您在此处看到的那样,当您想要更改对象并进行这些更改时反映在函数之外。

      另一方面,如果您想对对象进行更改但不影响原始对象,则不希望通过引用传递。例如,如果您有一个对向量执行 argsort 的函数,并且 argsort 的实现也对向量进行了排序。您不想实际修改向量,如果您通过引用传递它会这样做。但是,如果您通常将向量传递给函数,它只会将该向量复制到一个新的临时变量中并对该变量进行排序,而不会改变初始向量。

      另外,请注意某些语言,例如 python(我认为是 Java)总是通过引用传递。

      【讨论】:

      • Also, be warned that some languages such as python (and I think Java) always pass by reference. 这不是真的,至少对于 C++ 中如何定义 "passed-by-reference" 来说不是这样。如果你有一个def get_string(the_string): the_string = 'something' 并且你有get_string(val),那么val 将不会持有something。在 Python、Java、JavaScript 中,它是 “按值传递”,但传递的值是引用(不可变基元除外)。所以从 c++ 的角度来看,Python、Java、JS,... 做一个 "pass-by-reference-copy""pass-by-value-copy" .
      猜你喜欢
      • 2010-09-24
      • 2020-05-14
      • 2014-07-26
      • 1970-01-01
      • 2010-10-10
      • 1970-01-01
      • 1970-01-01
      • 2023-03-03
      • 1970-01-01
      相关资源
      最近更新 更多