【问题标题】:Is Passing a Dynamically Allocated Array to a Function in C an Instance of Pass-by-value or Pass-by-reference?将动态分配的数组传递给 C 中的函数是按值传递还是按引用传递的实例?
【发布时间】:2015-10-19 10:18:12
【问题描述】:

为了演示,这里是重新创建将动态分配的数组传递给函数的实例的示例代码。

#include <stdio.h>
#include <stdlib.h>
void fx1(int* arr) {/* code here */ }
int main() {
    int *arr = (int *) malloc(sizeof(int) * 10);
    fx1(arr);
    free(arr);
    return 0;
}

在示例中,我首先创建了一个动态分配的数组arr。然后,我将它传递给一个名为 fx1 的函数。 标题正是我的问题。将动态分配的数组传递给 C 中的函数是按值传递还是按引用传递的实例?如果您对此有答案,我还想要一份参考资料(书籍、文档等)。

【问题讨论】:

  • arr 是一个指针。它指向malloc 分配的数组的第一个元素。您将指针传递给该数组的第一个元素。将这种情况称为“传递数组”是对符号的滥用。
  • C 没有通过引用。
  • 谢谢。我注意到 (1) C 没有按引用传递,并且 (2) arr 是指针,而不是数组。

标签: c arrays dynamic-allocation


【解决方案1】:

在 C 中,一切都是按值传递的。在您的具体示例中,arr 是。您没有 C++ 或 Java 中的引用。

我们以 C++ 为例:

void foo(int& i) {
    ++i;
}

int main() {
    int i = 1;

    foo();
}

这里使用了真实的引用。 i 通过引用传递,foo 通过对 i 的引用修改 i不会发生“按值复制”。

OTOH,在 C 中,您没有引用。你只能写类似

void foo(int* i) {
    ++*i;
}

int main() {
    int i = 1;

    foo(&i);
}

要在 C 中“通过引用”1 传递一些东西,你需要传递一个指向它的指针,就像你做的那样。指针本身是按值传递,但它引用指向一个可由函数分配器修改的内存区域(此处为i)。

最后,如果您想在 C 中“通过引用”传递某些内容,则始终涉及按值复制。在 C++ 中并非如此。

引自 K&R,1.8 参数 - 按值调用:

在 C 中,所有函数参数都是按值传递的。''


1 请注意,这是在双引号内。 C 没有“按引用传递”。期间。

【讨论】:

  • "在 C 中,一切都是按值传递的。" “要在 C 中“通过引用”传递某些东西,您需要传递一个指向它的指针。”两者似乎是矛盾的。你能从 C 的角度多解释一下吗?
  • @Mercado 为了解决矛盾的部分,我在“by reference”周围加上了双引号。从技术上讲,C 中没有这样的东西。无论如何,您可以将指向某个内存位置的指针传递给函数,让函数对其进行修改。
  • 好的。此信息的任何基础/来源,尤其是“在 C 中,一切都是按值传递的。”?
  • 我认为我没有传递指向“它”的指针。您可以更改数组的内容,但相反,如果您在函数调用中更改“it”(arr) 的值,通过使用 malloc 给它一个新的内存地址,新的内存地址将不会从哪里出现您调用了函数调用(这是主函数),因为 arr 是函数中的局部变量。如果我错了,请纠正我,我想了解说“按引用传递”的真正含义,在涉及数组时似乎令人困惑。
  • 我是这么看的:引用比 C 提供的抽象更高。所以任何“引用”都是应用程序语义的问题,而不是 C。
【解决方案2】:

它是“两者”:

指针按值传递,数组“按引用”传递。

C Standard draft, N1256:

6.5.2.2 函数调用
...
4 参数可以是任何对象类型的表达式。在准备调用函数时,参数 被评估,并且每个参数被赋值 对应的参数。
...

我将“both”和“by reference”放在引号中,因为在 C 中没有引用。指针不是引用,而是用于“传递数组”给函数时,大致相当,如果函数修改数组,调用者可以看到更改。我认为这有助于理解这里发生的事情。
我们说一个数组在传递给一个函数时衰减为一个指针。 “衰减”是因为指针丢失了一些信息,即数组的长度。所以说这类似于“通过引用传递”只是从应用程序的角度来看。

【讨论】:

  • 解释,还是出处?
  • 这就解释了为什么指针是按值传递的,因为函数调用中的指针是另一个与main中不同的局部变量。我说的对吗?
  • 是的,完全正确。函数中的指针是一个副本,但指向的是同一个数组。
  • 谢谢。数组通过引用传递的原因是什么?
  • 严格来说,在 C 中一切都是按值传递的。所以你按值传递指针。但是指针有点像引用,所以你可以说你“通过引用”传递一个数组。在 C 中,没有办法通过值传递数组,这是不可能的。
猜你喜欢
  • 2022-10-24
  • 2012-02-26
  • 1970-01-01
  • 1970-01-01
  • 2015-11-28
  • 2014-04-08
  • 1970-01-01
  • 2013-10-24
  • 2014-12-26
相关资源
最近更新 更多