如果C语言不支持通过引用传递变量,为什么这样做呢?
#include <stdio.h>
void f(int *j) {
(*j)++;
}
int main() {
int i = 20;
int *p = &i;
f(p);
printf("i = %d\n", i);
return 0;
}
输出:
$ gcc -std=c99 test.c
$ a.exe
i = 21
如果C语言不支持通过引用传递变量,为什么这样做呢?
#include <stdio.h>
void f(int *j) {
(*j)++;
}
int main() {
int i = 20;
int *p = &i;
f(p);
printf("i = %d\n", i);
return 0;
}
输出:
$ gcc -std=c99 test.c
$ a.exe
i = 21
当前回答
简单回答:是的,C确实使用指针通过引用实现了参数传递。
在实现参数传递时,编程语言的设计者使用三种不同的策略(或语义模型):将数据传输到子程序,从子程序接收数据,或者两者都做。这些模型通常分别称为in模式、out模式和inout模式。
语言设计者设计了几个模型来实现这三个基本参数传递策略:
值传递(在模式语义中) 结果传递(out模式语义) 值-结果传递(inout模式语义) 引用传递(inout模式语义) 名称传递(inout模式语义)
Pass-by-reference is the second technique for inout-mode parameter passing. Instead of copying data back and forth between the main routine and the subprogram, the runtime system sends a direct access path to the data for the subprogram. In this strategy the subprogram has direct access to the data effectively sharing the data with the main routine. The main advantage with this technique is that its absolutely efficient in time and space because there is no need to duplicate space and there is no data copying operations.
C中的参数传递实现: C使用指针作为参数实现了值传递和引用传递(inout模式)语义。指针被发送到子程序,根本不复制实际数据。然而,由于指针是主例程数据的访问路径,子程序可以改变主例程中的数据。C采用了ALGOL68的方法。
c++中的参数传递实现: c++还使用指针实现了引用传递(inout模式)语义,也使用了一种特殊类型的指针,称为引用类型。引用类型指针在子程序内部隐式地解引用,但它们的语义也是引用传递的。
这里的关键概念是引用传递实现了数据的访问路径,而不是将数据复制到子程序中。数据访问路径可以是显式解引用指针或自动解引用指针(引用类型)。
有关更多信息,请参阅Robert Sebesta所著的《编程语言的概念》,第10版,第9章。
其他回答
指针和引用是两个不同的东西。
有几件事我没有看到有人提到。
指针是某物的地址。指针可以像其他变量一样存储和复制。因此,它有一个大小。
引用应该被视为某个东西的别名。它没有大小,不能存储。它一定是指什么。不能为空或更改。好吧,有时候编译器需要将引用存储为指针,但这是实现细节。
有了引用,你就不会有指针的问题,比如所有权处理、空检查、使用时取消引用。
在C语言中,模拟了引用传递 通过传递变量的地址 (一个指针)并对其进行解引用 地址内的函数读取或 写出实际的变量。这将 被称为“C风格” 引用传递”。
来源:www-cs-students.stanford.edu
代码片段(有微小修改)
void add_number(int * const a) {
*a = *a + 2;
}
在c++中也存在,在语义上等价于
void add_number(int &a) {
a = a + 2;
}
在这两种情况下,编译器都希望生成相同的add_number函数二进制代码。现在,当您将一个整数视为一个值时,该值将由它的引用传递,在上面的模式中,引用在技术上显示为指针。
结论 C支持通过引用传递实例的语义。 即使在技术上使用int *a你也传递了*a,它是一个引用。
您的示例之所以能够工作,是因为您将变量的地址传递给了一个使用解引用操作符操作其值的函数。
虽然C不支持引用数据类型,但您仍然可以通过显式传递指针值来模拟引用传递,如您的示例所示。
c++引用数据类型功能较弱,但被认为比继承自C的指针类型更安全。这将是您的示例,改编为使用c++引用:
void f(int &j) {
j++;
}
int main() {
int i = 20;
f(i);
printf("i = %d\n", i);
return 0;
}
您正在按值传递一个指针(地址位置)。
这就像是在说“这里有我想让你更新的数据”。