如果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语言中,一切都是值传递。指针的使用给我们一种通过引用传递的错觉,因为变量的值发生了变化。但是,如果您要打印指针变量的地址,您将看到它不会受到影响。地址值的副本被传递给函数。下面是一个演示片段。
void add_number(int *a) {
*a = *a + 2;
}
int main(int argc, char *argv[]) {
int a = 2;
printf("before pass by reference, a == %i\n", a);
add_number(&a);
printf("after pass by reference, a == %i\n", a);
printf("before pass by reference, a == %p\n", &a);
add_number(&a);
printf("after pass by reference, a == %p\n", &a);
}
before pass by reference, a == 2
after pass by reference, a == 4
before pass by reference, a == 0x7fff5cf417ec
after pass by reference, a == 0x7fff5cf417ec
其他回答
你不是通过引用传递int型,而是通过值传递指向int型的指针。不同的语法,相同的意思。
您正在按值传递一个指针(地址位置)。
这就像是在说“这里有我想让你更新的数据”。
在C语言中,模拟了引用传递 通过传递变量的地址 (一个指针)并对其进行解引用 地址内的函数读取或 写出实际的变量。这将 被称为“C风格” 引用传递”。
来源:www-cs-students.stanford.edu
在C语言中,为了通过引用传递,你使用了地址操作符&,它应该用于一个变量,但在你的例子中,因为你已经使用了指针变量p,你不需要在它前面加上地址操作符。如果你使用&i作为参数:f(&i),这将是正确的。
你也可以添加这个,来解引用p,看看这个值如何匹配i:
printf("p=%d \n",*p);
将指针称为引用(如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语言只采用值传递。