【问题标题】:C++ argument passingC++ 参数传递
【发布时间】:2016-01-04 06:00:02
【问题描述】:

好的,所以我刚开始学习 C++,我发现参数传递的来龙去脉有点令人困惑。我在我的 C++ 书中遇到了以下行;

在 C++ 中,通过引用传递有两种方式:使用指针和使用引用。

然后继续显示一个程序,该程序切换两个 int 值 x 和 y 的值(如下所示)。我想知道,在这种情况下,swap() 函数的参数真的是通过引用传递的吗?我以为它们是按地址传递的,有人告诉我这只是按值传递的一种特殊情况。

//Listing 9.6 Demonstrates passing by reference 

#include <iostream.h>

void swap(int *x, int *y);

int main()
{
    int x = 5, y = 10;

    cout << "Main.  Before swap, x:  " << x
         << " y: " << y << "\n";
    swap(&x,&y);
    cout << "Main. After swap, x:  " << x
         << " y: " << y << "\n";
    return 0;
}
void swap(int *px, int *py) 
{
    int temp;

    cout << "Swap.  Before swap, *px: "
         << *px << " *py: " << *py << "\n";

    temp = *px;
    *px = *py;
    *py = temp;

    cout << "Swap. After swap, *px: " << *px
         << " *py: " << *py << "\n";

}

【问题讨论】:

  • 你应该知道call-by-address和call-by-reference是一样的。
  • swap 的参数(指向int 的类型指针)当然不是按引用传递,而是按值传递。不过,它们是地址。
  • 您需要考虑“通过引用”指的是哪些对象。指针(参数)引用变量,因此您通过引用传递变量,即使引用它们的指针是按值传递的。

标签: c++ parameter-passing


【解决方案1】:

抽象级别的完美融合。

最低级别:当您按值传递 C++ 指针时,指针值被复制。

更高层次:通常是指针指向某个东西,而那个东西在逻辑上是通过引用传递的。

在 C++ 中通过引用传递最直接的方法是使用引用参数。在幕后,C++ 引用可以(在某些特定情况下)是一个指针,但没有办法访问或确定有关该指针值的任何内容。所以说引用是按值传递或复制是没有意义的,而是我们谈论绑定引用或绑定到引用。

在正确的程序中,引用不能是空引用,这对于作为形式参数类型的引用来说是一个明显的优势。

另一个优点是对const的引用可以绑定到一个临时的,例如

void foo( const std::string& s ) ...

可以这样称呼

foo( "Blah!" )

当使用指针来“实现”逻辑传递引用时,这是不可能的。

【讨论】:

    【解决方案2】:

    你是对的。功能

    void swap(int *x, int *y);
    

    正在接受它的参数按值。因为参数是指针,它可以取消引用它们,从而修改它们指向的内存。然而,指针本身(地址)是按值传递的。您可以看到,如果 swap 为其参数之一分配不同的值(地址),则更改不会反映在调用者中。

    int a = 1;
    int b = 2;
    int * pa = &a;
    int * pb = &b;
    swap(pa, pb);
    assert((pa == &a) && (pb == &b));
    

    尝试添加类似的东西

    px += 12;
    py += 17;
    

    swap 的末尾。 assertion 仍将保留。

    在 C++ 中,指针本身就是一个对象。它有一个值(它指向的地址)并且可以被复制或分配一个不同的值。它也可以像其他对象一样按引用或按值传递。

    通过引用获取指针的函数如下所示。

    #include <iostream>
    
    void
    pointer_by_reference(int * & p)
    {
      p = nullptr;
    }
    
    int
    main()
    {
      int a;
      int * pa = &a;
      pointer_by_reference(pa);
      std::cout << "&a = " << &a << ", pa = " << pa << "\n";
    }
    

    可能的输出:

    &a = 0x7ffcfdf2e00c, pa = 0
    

    如您所见,pointer_by_reference 改变了pa 的值。

    【讨论】:

      【解决方案3】:

      这里是按地址调用,因为您正在捕获地址变量。在 Call by Ref 的情况下,我们使用 void swap(int &amp;x, int &amp;y); 作为原型。

      详情查看Diff Between Call By Reference And Call By Pointer

      另见知识What are the differences between a pointer variable and a reference variable in C++?

      【讨论】:

        【解决方案4】:

        参数传递基本上有两种技术。

        1. 按值调用
        2. 按引用调用(也称为按地址调用)

        您的代码确实是通过引用传递参数。

        使用按值调用时,当数据传递给过程中的参数时,只有值可用于过程的参数。因此,您对过程中的参数所做的任何更改都不会影响调用例程的变量。

        但是通过引用调用,变量的地址可用于参数。换句话说,参数实际上指向与变量相同的位置。所以改变过程中的参数实际上改变了传递给它的变量。

        【讨论】:

        • 代码没有通过引用传递参数。调用者明确获取地址并按值传递。
        • 在大多数书籍中被称为通过引用。
        猜你喜欢
        • 1970-01-01
        • 2010-12-12
        • 1970-01-01
        • 2019-04-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多