C++ 参数传递
C++ argument passing
好的,所以我刚开始学习 C++,我发现参数传递的来龙去脉有点令人困惑。我在我的 C++ 书中遇到了以下行;
In C++, passing by reference is accomplished in two ways: using pointers and using references.
然后继续显示一个程序,该程序切换两个 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-value
- Call-by-reference(也称为call-by-address)
您的代码确实是通过引用传递参数。
使用 call-by-value,当数据传递给过程中的参数时,只有该值可用于过程的参数。因此,您在过程中对参数所做的任何更改都不会影响调用例程的变量。
但是对于call-by-reference,变量的地址可用于参数。换句话说,参数实际上指向与变量相同的位置。因此,在过程中更改参数实际上会更改传递给它的变量。
此处是按地址调用,因为您正在捕获地址变量。在 Call by Ref 的情况下,我们使用 void swap(int &x, int &y);
作为原型。
查看详情Diff Between Call By Reference And Call By Pointer
另见知识What are the differences between a pointer variable and a reference variable in C++?
你是对的。函数
void swap(int *x, int *y);
正在接受它的论据by-value。因为参数是指针,所以它可以解除对它们的引用,从而修改它们指向的内存。然而,指针本身(地址)被传递 by-value。您可以看到,如果 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
的末尾。 assert
离子仍然存在。
在 C++ 中,指针本身就是一个对象。它有一个值(它指向的地址)并且可以被复制或分配一个不同的值。它也可以像其他对象一样传递 by-reference 或 by-value。
接受指针的函数 by-reference 看起来像这样。
#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
的值。
很好地融合了抽象层次。
最低级别:当您按值传递 C++ 指针时,指针值被复制。
更高级别:通常指针指向某物,并且该某物逻辑上通过引用传递。
在 C++ 中通过引用传递最直接的方法是使用引用参数。在幕后,C++ 引用可以(在某些给定情况下)是一个指针,但无法访问或确定有关该指针值的任何内容。所以说引用是按值传递或复制是没有意义的,相反我们谈论 binding the reference 或 binding to参考。
在正确的程序中,引用不能是 null-reference,这是作为正式参数类型的引用的一个明显优势。
另一个优点是对 const
的引用可以绑定到临时对象,例如
void foo( const std::string& s ) ...
可以这样称呼
foo( "Blah!" )
当使用指向“实现”逻辑的指针而不是引用时,这是不可能的 pass-by-reference。
好的,所以我刚开始学习 C++,我发现参数传递的来龙去脉有点令人困惑。我在我的 C++ 书中遇到了以下行;
In C++, passing by reference is accomplished in two ways: using pointers and using references.
然后继续显示一个程序,该程序切换两个 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-value
- Call-by-reference(也称为call-by-address)
您的代码确实是通过引用传递参数。
使用 call-by-value,当数据传递给过程中的参数时,只有该值可用于过程的参数。因此,您在过程中对参数所做的任何更改都不会影响调用例程的变量。
但是对于call-by-reference,变量的地址可用于参数。换句话说,参数实际上指向与变量相同的位置。因此,在过程中更改参数实际上会更改传递给它的变量。
此处是按地址调用,因为您正在捕获地址变量。在 Call by Ref 的情况下,我们使用 void swap(int &x, int &y);
作为原型。
查看详情Diff Between Call By Reference And Call By Pointer
另见知识What are the differences between a pointer variable and a reference variable in C++?
你是对的。函数
void swap(int *x, int *y);
正在接受它的论据by-value。因为参数是指针,所以它可以解除对它们的引用,从而修改它们指向的内存。然而,指针本身(地址)被传递 by-value。您可以看到,如果 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
的末尾。 assert
离子仍然存在。
在 C++ 中,指针本身就是一个对象。它有一个值(它指向的地址)并且可以被复制或分配一个不同的值。它也可以像其他对象一样传递 by-reference 或 by-value。
接受指针的函数 by-reference 看起来像这样。
#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
的值。
很好地融合了抽象层次。
最低级别:当您按值传递 C++ 指针时,指针值被复制。
更高级别:通常指针指向某物,并且该某物逻辑上通过引用传递。
在 C++ 中通过引用传递最直接的方法是使用引用参数。在幕后,C++ 引用可以(在某些给定情况下)是一个指针,但无法访问或确定有关该指针值的任何内容。所以说引用是按值传递或复制是没有意义的,相反我们谈论 binding the reference 或 binding to参考。
在正确的程序中,引用不能是 null-reference,这是作为正式参数类型的引用的一个明显优势。
另一个优点是对 const
的引用可以绑定到临时对象,例如
void foo( const std::string& s ) ...
可以这样称呼
foo( "Blah!" )
当使用指向“实现”逻辑的指针而不是引用时,这是不可能的 pass-by-reference。