如果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实际上支持引用传递。

大多数语言要求语法糖通过引用而不是值传递。(例如,c++在参数声明中要求&)。

C也需要语法糖。在形参类型声明中是*,在实参中是&。*和&是C语言中引用传递的语法。

现在有人可能会说,真正的引用传递应该只要求参数声明的语法,而不是参数方面的语法。

但是现在出现了c#,它支持引用传递,并且在参数和参数方面都需要语法糖。

C没有by-ref传递的参数导致表达它的语法元素显示底层技术实现,这根本不是一个参数,因为这或多或少适用于所有实现。

唯一剩下的论点是,在C中传递ref不是一个单一的特征,而是结合了两个现有的特征。(获取ref的参数为&,期望ref的类型为*。)例如,c#确实需要两个语法元素,但它们不能单独使用。

这显然是一个危险的论点,因为语言中的许多其他特征是由其他特征组成的。(类似c++中的字符串支持)

指针和引用是两个不同的东西。

有几件事我没有看到有人提到。

指针是某物的地址。指针可以像其他变量一样存储和复制。因此,它有一个大小。

引用应该被视为某个东西的别名。它没有大小,不能存储。它一定是指什么。不能为空或更改。好吧,有时候编译器需要将引用存储为指针,但这是实现细节。

有了引用,你就不会有指针的问题,比如所有权处理、空检查、使用时取消引用。

因为在上面的代码中没有引用传递。使用指针(如void func(int* p))是通过地址传递的。 这是c++中的引用传递(在C中不起作用):

void func(int& ref) {ref = 4;}

...
int a;
func(a);
// a is 4 now

代码片段(有微小修改)

void add_number(int * const a) {
    *a = *a + 2;
}

在c++中也存在,在语义上等价于

void add_number(int &a) {
    a = a + 2;
}

在这两种情况下,编译器都希望生成相同的add_number函数二进制代码。现在,当您将一个整数视为一个值时,该值将由它的引用传递,在上面的模式中,引用在技术上显示为指针。

结论 C支持通过引用传递实例的语义。 即使在技术上使用int *a你也传递了*a,它是一个引用。