6

我听说在“c”中我们可以通过“按值调用”或“按引用调用”传递参数。但是在一本书中提到,我们可以通过两种方式传递参数,但没有“通过引用”,但我实际上通过“通过引用”传递了大部分参数。

那么为什么提到“C甚至有”通过引用传递“?

将不胜感激详细的描述。

4

2 回答 2

23

C 参数总是按值而不是按引用传递。但是,如果您将对象的地址视为对该对象的引用,那么您可以按值传递该引用。例如:

void foo(int *x)
{
    *x = 666;
}

你在评论中问:

那么当我们可以按值传递所有参数时,为什么我们需要 C 中的指针呢?

因为在仅支持按值传递的语言中,缺少指针会受到限制。这意味着您不能编写这样的函数:

void swap(int *a, int *b)
{
    int temp = *a;
    *b = *a;
    *a = temp;
}

例如,在 Java 中,不可能编写该函数,因为它只有按值传递并且没有指针。

在 C++ 中,您将使用如下引用编写函数:

void swap(int &a, int &b)
{
    int temp = a;
    b = a;
    a = temp;
}

同样在 C# 中:

void swap(ref int a, ref int b)
{
    int temp = a;
    b = a;
    a = temp;
}
于 2013-06-18T12:18:28.947 回答
18

“引用语义”的概念是一个抽象的理论概念,这意味着您可以通过为该函数提供对数据的引用来修改现有数据。

问题是引用语义是否可以通过一种语言来实现。在 C 中,您可以通过使用指针来获得引用语义。这意味着您可以获得所需的行为,但您需要自己从各种位和部分(指针类型、地址运算符、取消引用运算符、将指针作为函数参数传递(“按值”))组装它。

相比之下,C++ 包含本机引用类型,因此直接在语言中实现引用语义。

其他语言对此有不同的方法,例如,在 Python 中,默认情况下很多东西都是引用(并且存在差异,例如,列表之间a = ba = b[:]何时b)。语言是否以及如何提供参考与价值语义是语言设计的重要组成部分。

于 2013-06-18T12:20:35.763 回答