“按引用传递”也可以称为“按指针传递”吗?

Can Pass by Reference also be called as Pass by Pointer?

提问人:YUMI 提问时间:12/29/2020 最后编辑:YUMI 更新时间:12/30/2020 访问量:128

问:

我目前正在阅读将参数传递给 C 函数的方法。在阅读过程中,我开始知道在 C 语言中有两种方法可以将参数传递为按值传递和按引用传递。 然后我又读到,我们也可以将指向变量的指针作为参数传递。

beginnersbook 网站提到这种方法是通过引用传递的。

在此示例中,我们将传递指向函数的指针。当我们将指针作为参数而不是变量传递时,将传递变量的地址而不是值。因此,函数使用指针所做的任何更改都将永久地在传递变量的地址处进行。这种技术在 C 中称为引用调用

我知道当我们需要更改或访问原始变量时,我们可以传递指针变量或带有 & 运算符的变量地址。我想知道这个通过指针传递是否可以称为通过引用传递。 指针传递也是一种引用传递的方法吗?

C 函数 指针

评论

1赞 Sprite 12/29/2020
C 没有引用,那是 C++ 的东西。
0赞 bruno 12/29/2020
...在 C++ 中,引用和指针不是一回事
2赞 John Bollinger 12/29/2020
C 没有两种参数传递方法。所有参数都按值传递。按值传递指针仍然是按值传递。
0赞 John Bollinger 12/29/2020
其他一些语言既有按值传递,也有按引用传递(例如 C++),有些语言只按引用传递(例如 Fortran)。我想你引用的网站是试图为初学者简化,但IMO你描述的表示对他们不利。

答:

7赞 dbush 12/29/2020 #1

从技术上讲,C 语言中函数的所有参数都是按值传递的。与 C++ 不同,该语言不支持真正的引用。

在 C 语言中,可以通过传递(按值)要修改的变量的地址来模拟通过引用传递,然后取消引用该地址以修改指向的值。然而,这不是真的,通过引用传递。

评论

0赞 YUMI 12/29/2020
所以这种对引用的不支持一定是我的 C 函数的原因 - void swapNums(int &x, int &y);然后抛出一个编译时间。感谢您的澄清。
1赞 dbush 12/29/2020
@Outlier 没错,这是一个C++功能。
1赞 Eric Postpischil 12/30/2020
“然而,这不是真正的参考”→如果你烤蛋糕,它就不是真正的蛋糕,因为你不是从面包店买的。事实上,这项工作确实完成了:该函数能够访问一个对象,因为它被赋予了对该对象的引用。
2赞 Eric Postpischil 12/29/2020 #2

C 中的指针是引用。C 2018 6.2.5 20说道:

...指针类型描述一个对象,其值提供对所引用类型的实体的引用...

当您将指针传递给函数时,您将向函数传递对指针指向的任何对象的引用。指针本身是按值传递的,但是,由于指针是引用,并且您正在传递它,因此通过引用传递对象的描述是准确的。

在 C++ 开发之前,对此没有争议;人们说他们通过引用传递一个对象来描述传递指向该对象的指针。C++ 在其语言中采用“引用”一词作为新功能的名称,因此,在 C++ 术语中,“引用”通常是指该功能,除非上下文另有说明或明确说明。但是,在 C 中,我们不受 C++ 术语的约束,并且通过引用传递的原始含义仍然准确。

1赞 Serge 12/29/2020 #3

通常,“c”中函数的所有参数都是“按值”传递的。这意味着如果在函数中修改了参数,则调用方将看不到此修改:

void foo(int val) {
   ...
   val = newval;
   ...
}
void bar() {
   foo(4);
}

上面示例中的值可以在“foo”中修改和使用,但“bar”不会看到更新。val

为了使更新在调用方中可见,使用了指针。

void foo(int *arg) {
   ...
   *arg = 5;
   ...
}
void bar () {
   int x = 4;
   foo(&x);
   // x will be 5 here
}

在上面的例子中,“x”的地址将被传递给函数 foo,它将在函数内部用于修改“x”的值。*arg

可以修改 foo 内部指针的值,因为它本身是按值传递的

void foo(int *arg) {
   arg = newAddress;
}

但是函数“bar”也不会看到这种修改。

因此,“c”中没有真正的“引用”,但是有些人用它来指针的传递。

评论

0赞 YUMI 12/29/2020
明白了。谢谢,我还有另一个问题。此处的函数被定义为接受指针类型参数。因此,当我们使用 & 作为 foo(&x) 调用函数时,我们直接传递了一个地址,对吧?我们不能传递指向它的指针吗,我的意思是我应该担心我应该以哪种方式调用函数吗?
1赞 Serge 12/30/2020
int *是指针类型 (to int) 的声明。指针本质上是数据的地址(在本例中为 int 数据)。 是获取变量地址的一种方式。你可以声明一个指针,并以这种方式为它赋值:然后你可以调用&xint *y = &x;foo(y);