我听说在“c”中我们可以通过“按值调用”或“按引用调用”传递参数。但是在一本书中提到,我们可以通过两种方式传递参数,但没有“通过引用”,但我实际上通过“通过引用”传递了大部分参数。
那么为什么提到“C甚至有”通过引用传递“?
将不胜感激详细的描述。
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;
}
“引用语义”的概念是一个抽象的理论概念,这意味着您可以通过为该函数提供对数据的引用来修改现有数据。
问题是引用语义是否可以通过一种语言来实现。在 C 中,您可以通过使用指针来获得引用语义。这意味着您可以获得所需的行为,但您需要自己从各种位和部分(指针类型、地址运算符、取消引用运算符、将指针作为函数参数传递(“按值”))组装它。
相比之下,C++ 包含本机引用类型,因此直接在语言中实现引用语义。
其他语言对此有不同的方法,例如,在 Python 中,默认情况下很多东西都是引用(并且存在差异,例如,列表之间a = b
和a = b[:]
何时b
)。语言是否以及如何提供参考与价值语义是语言设计的重要组成部分。