C语言中的函数引用调用

你好,未来的程序员们!今天,我们将踏上一段激动人心的旅程,探索C编程世界的概念——函数的“引用调用”。如果你是编程新手,不用担心;我会一步步引导你,就像我多年来指导无数学生一样。所以,拿起你最喜欢的饮料,舒服地坐好,让我们一起深入了解一下!

C - Function call by reference

C语言中的地址运算符 (&)

在我们理解函数的引用调用之前,我们需要熟悉C语言中一个非常重要的符号:&(地址运算符)。这个小字符被称为“地址运算符”,就像一根魔杖,可以揭示我们的变量在计算机内存中的秘密位置。

让我们来看一个简单的例子:

#include <stdio.h>

int main() {
int age = 25;
printf("age 的值是: %d\n", age);
printf("age 的地址是: %p\n", &age);
return 0;
}

在这段代码中,我们不仅打印了 age 的值(25),还打印了它在内存中的地址。%p 格式指定符用于打印内存地址。

当你运行这个程序时,你可能会看到类似的结果:

age 的值是: 25
age 的地址是: 0x7ffd5e8e9944

在 "age 的地址是:" 后面那个奇怪的数字实际上是内存地址!这是你的计算机决定存储 age 变量的位置。把它想象成变量在计算机内存广阔社区中的家庭住址。

C语言中的指针是什么?

既然我们知道如何找到一个变量的地址,那么让我们来谈谈指针。如果地址像是家庭地址,那么指针就像是可以引导你到那个地址的GPS导航器。

在C语言中,指针是一个存储另一个变量内存地址的变量。我们通过使用星号 (*) 符号来声明指针。

这里有一个例子:

#include <stdio.h>

int main() {
int age = 25;
int *ptr_age = &age;

printf("age 的值是: %d\n", age);
printf("age 的地址是: %p\n", &age);
printf("ptr_age 的值是: %p\n", ptr_age);
printf("ptr_age 指向的值是: %d\n", *ptr_age);

return 0;
}

在这段代码中,ptr_age 是一个指针,它存储了 age 的地址。当我们使用 *ptr_age 时,我们是在询问 ptr_age 指向的地址处存储的值。

输出可能看起来像这样:

age 的值是: 25
age 的地址是: 0x7ffd5e8e9944
ptr_age 的值是: 0x7ffd5e8e9944
ptr_age 指向的值是: 25

看到 ptr_age 存储的地址与 age 的地址相匹配了吗?这是因为 ptr_age 指向 age

C语言中的引用调用是如何工作的?

现在我们理解了指针,我们可以探索函数的引用调用。当我们通过引用调用函数时,我们实际上是将变量的地址传递给函数,而不是其值。这允许函数直接修改原始变量。

让我们来看一个例子:

#include <stdio.h>

void increment(int *num) {
(*num)++;
}

int main() {
int x = 5;
printf("increment 之前: x = %d\n", x);
increment(&x);
printf("increment 之后: x = %d\n", x);
return 0;
}

在这段代码中,我们将 x 的地址传递给 increment 函数。然后该函数使用这个地址直接修改 x 的值。

输出将是:

increment 之前: x = 5
increment 之后: x = 6

increment 函数能够改变 main 函数中 x 的值,因为它接收的是 x 的地址,而不是其值的副本。

混合使用值调用和引用调用

在C语言中,我们可以在同一个函数中混合使用值调用和引用调用。当我们要修改某些参数而其他参数保持不变时,这非常有用。

这里有一个例子:

#include <stdio.h>

void modify(int *a, int b, int *c) {
(*a)++;
b++;
(*c)++;
}

int main() {
int x = 1, y = 2, z = 3;
printf("modify 之前: x = %d, y = %d, z = %d\n", x, y, z);
modify(&x, y, &z);
printf("modify 之后: x = %d, y = %d, z = %d\n", x, y, z);
return 0;
}

在这个例子中,xz 是通过引用传递的,而 y 是通过值传递的。

输出将是:

modify 之前: x = 1, y = 2, z = 3
modify 之后: x = 2, y = 2, z = 4

注意 xz 发生了变化,但 y 保持不变?这是因为函数只接收到 y 的副本,而不是它的地址。

下面是一个表格,总结了值调用和引用调用的不同之处:

方面 值调用 引用调用
传递的内容 值的副本 变量的地址
是否可以修改原变量
语法 function(variable) function(&variable)
函数参数 普通变量 指针

就这样!我们已经覆盖了C语言中函数引用调用的基础知识。记住,像学习任何新技能一样,实践是关键。尝试编写使用引用调用的自己的函数,并尝试不同的场景。在你意识到之前,你将能够像专业人士一样操作内存地址!

祝编码愉快,愿你的指针总是指向正确的方向!

Credits: Image by storyset