C和C++中引用传递的含义?

Meaning of pass by reference in C and C++?

我对 C 和 C++ 中 "pass by reference" 的含义感到困惑。

在 C 中,没有引用。所以我想通过引用传递意味着传递一个指针。但是为什么不把它称为指针传递呢?

在 C++ 中,我们同时拥有指针和引用(以及接近的迭代器之类的东西)。那么这里的引用传递是什么意思?

"Pass by reference" (or "call by reference") is a term for a type of parameter passing when calling a function, and the idea is older than C++. It does not necessarily have to be done using C++ "references"。 C 没有内置机制来执行此操作,因此您必须使用指针。

引用通常是引用其他内容的实例。因此,在更广泛的意义上,指针也可以被视为引用的一种可能实现。 C++ 中的引用只是称为引用,因为除了引用某些东西外,它们不提供任何其他功能。

传引用一般用来区别传值。无论是通过指针还是通过引用,通常只是一个次要的细节。但是,对于 C++ 引用,恕我直言,函数参数的目的是什么。例如:

int foo(int& a);         // pass-by-reference
int foo(const int& a);   // is pratically pass-by-value 
                         // (+ avoiding the copy of the parameter)

另一方面,对于引用(与指针相比),它是按值传递还是按引用传递在调用站点上并不那么明显。例如

int x;
int y = foo(x);  // could be pass-by-value or pass-by-reference
int z = foo(&x); // obviously pass-by-reference (as a pointer)

In C, there are no references

没有参考变量。但是您可以使用指针来引用对象。因此从抽象的角度来看,指针是"references"。

But then why not call it pass by pointer?

可以调用它通过指针传递。引用是比指针更通用的术语。当您想要讨论抽象并想要忽略实现细节时,通常最好使用更通用的术语。出于与调用变量 "integer" 而不是 "int32_t".

相同的原因,您可以将其称为按引用传递

In C++, we have both pointers and references (and stuff like iterators that lies close). So what does pass by reference mean here?

取决于上下文。通常它意味着函数参数是一个引用变量,但它也可以引用指针、迭代器、引用包装器……任何引用对象的东西。


引用是一个存在的抽象概念beyond c and c++; even beyond programming。在 c++ 中,该术语与引用变量有歧义,上下文和约定(不通用)决定了含义。

在口语中,"pass by reference"意味着,如果被调用者修改了它的参数,它会影响调用者,因为被调用者看到的参数指的是调用者看到的值。

该短语的使用独立于实际的编程语言,以及它如何调用事物(指针、引用等)。

在 C++ 中,按引用调用 可以使用引用 指针来完成。在C中,call-by-reference只能通过传递一个指针来实现

"Call by value":

void foo( int x )
{
    // x is a *copy* of whatever argument foo() was called with
    x = 42;
}

int main()
{
    int a = 0;
    foo( a );
    // at this point, a == 0
}

"Call by reference", C 风格:

void foo( int * x )
{
    // x is still a *copy* of foo()'s argument, but that copy *refers* to
    // the value as seen by the caller
    *x = 42;
}

int main()
{
    int a = 0;
    foo( &a );
    // at this point, a == 42
}

所以,严格来说,C中没有传递引用。您要么按值传递变量,要么传递指向该变量的指针 按值.

当你通过引用传递一些东西时,你是在处理地址而不是直接变量的值,如果你使用引用参数,你会得到你传入的变量的地址。

从那里你可以随心所欲地操纵它,因为如果你改变函数中的引用,你传入的变量将会改变。这是处理大量数据的更简单方法,它实际上只是节省了内存等。

假设您必须粉刷房子...

by value: 你把你家的复制品带给画家 => 辛苦了(也许在 rails 上)
by reference:你把你的住址告诉画家,他就可以来画了

C中有两个概念

1. 按值调用 - 这里传递值的副本,因此实际值不会在函数外发生变化。

2. 通过引用调用 - 但这里传递的是实际值(实际操作数的地址),因此它将全局更改值。

C++中有两个概念的地方

1.按值传递-与c相同,实际值不会改变,此值的范围仅具有功能。

2. 通过引用传递 - 传递实际值(实际操作数的地址),因此它将全局更改值,这意味着如果值被更改,那么它将影响整个程序。

在引用传递中,操作数的地址被传递,这就是为什么它被称为引用传递而不是指针。

在C中,没有任何引用变量,但是你可以使用指针传递引用。

在维基百科中,有这样的定义。 在按引用调用评估(也称为按引用传递)中,函数接收对用作参数的变量的隐式引用,而不是其值的副本。所以这个术语是指 Thomas 提到的参数传递类型。所以是的,因为 C 比 C++ 老,所以这个想法也比 C++ 老。

但是,在C++中,指针和引用都可以用于传递给函数(按地址调用和按引用调用)。实际上他们的工作方式是一样的,只有一点点不同。

  • 引用一旦创建,以后就不能引用 另一个对象;它无法重新安装。这通常是用 指针。
  • 引用不能为 NULL。指针通常设为 NULL 以指示 他们没有指向任何有效的东西。
  • 引用必须在声明时初始化。不存在这样的 指针限制

有了这些差异,如果您使用引用调用而不是指针调用,则可以减少出现 NULL 指针错误这类问题的可能性。

让我们来消除你的困惑。

In C, there are no references. So I guess pass by reference means passing a pointer. But then why not call it pass by pointer?

因为C 中传递的每个参数都是按值传递。甚至指针参数也是一个副本。但它包含(或指向,如果您愿意的话)相同的值——内存地址。这就是你如何改变它指向的变量,而不是指针本身。因为它是一个副本,所以无论你做什么都不会影响调用者级别的指针。

In C++, we have both pointers and references (and stuff like iterators that lies close). So what does pass by reference mean here?

这意味着,参数是调用者级别变量的别名,而不是副本,这允许我们更改它。

希望对您有所帮助。

只是为了补充答案,引用并不意味着通过地址引用。编译器可以使用任何方法来引用变量。