如果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 

当前回答

P是一个指针变量。它的值是i的地址。当你调用f时,你传递p的值,它是i的地址。

其他回答

“通过引用传递”(通过使用指针)从一开始就存在于C语言中。你为什么不这么认为?

在C语言中,为了通过引用传递,你使用了地址操作符&,它应该用于一个变量,但在你的例子中,因为你已经使用了指针变量p,你不需要在它前面加上地址操作符。如果你使用&i作为参数:f(&i),这将是正确的。

你也可以添加这个,来解引用p,看看这个值如何匹配i:

printf("p=%d \n",*p);

C中没有引用传递,但是p“指向”i,你通过值传递p。

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

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

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

将指针称为引用(如Java和Javascript所做的)与引用传递(pass-by-reference)是完全不同的用法。C不支持引用传递。下面是重新编写的示例,以显示它不是真正地通过引用传递值,而是通过值传递指针。

#include <stdio.h>

void f(int *j) {
  int k = (*j) + 1;
  j = &k;
}

int main() {
  int i = 20;
  int *p = &i;
  f(p);
  printf("i = %d\n", i);
  printf("j = %d\n", *p);


  printf("i(ptr) = %p\n", &i);
  printf("j(ptr) = %p\n", p);


  return 0;
}

这是输出

i = 20
j = 20
i(ptr) = 0x7ffdfddeee1c
j(ptr) = 0x7ffdfddeee1c

如您所见,值保持不变,但更重要的是指针也没有改变。然而,c++允许通过引用传递。下面是通过c++编译器实现的相同示例,但在头文件中添加了&号,使其成为引用参数。

#include <stdio.h>

void f(int *&j) {   // note the & makes this a reference parameter.
                    // can't be done in C
  int k = (*j) + 1;
  j = &k;
}

int main() {
  int i = 20;
  int *p = &i;
  f(p);
  printf("i = %d\n", i);
  printf("j = %d\n", *p);


  printf("i(ptr) = %p\n", &i);
  printf("j(ptr) = %p\n", p);


  return 0;
}

这是输出

i = 20
j = 21
i(ptr) = 0x7ffcb8fc13fc
j(ptr) = 0x7ffcb8fc13d4

注意,我们可以改变实际的指针!

作为参考,The Dragon Book是一本关于编译器的经典计算机科学教科书。因为它是有史以来最受欢迎的编译器书籍(至少在我上大学的时候是这样,也许我错了),我猜绝大多数设计语言或编写编译器的人都是从这本书中学习的。本书的第一章非常清楚地解释了这些概念,并解释了为什么C语言只采用值传递。