Cprogramming 简明教程
Function Call by Reference in C
函数可以通过两种方式调用:(a)按值调用和 (b) 按引用调用。在本章中,我们将解释按引用调用函数的机制。
There are two ways in which a function can be called: (a) Call by Value and (b) Call by Reference. In this chapter, we will explain the mechanism of calling a function by reference.
让我们从简要概述“指针”和“地址运算符 (&)”开始本章。为了完全理解按引用调用的机制,学习这两个概念非常重要。
Let us start this chapter with a brief overview on "pointers" and the "address operator (&)". It is important that you learn these two concepts in order to fully understand the mechanism of Call by Reference.
The Address Operator (&) in C
在 C 语言中,变量是一个已命名的内存位置。当声明变量时,编译器将在内存中分配一个随机位置,并在内部使用用户定义的名称标识该位置。
In C language, a variable is a named memory location. When a variable declared, the compiler allocates a random location in the memory and internally identifies the location with the user-defined name.
要获取创建变量的地址,我们使用 address (&) operator 。
To fetch the address at which the variable has been created, we use the address (&) operator.
What is a Pointer in C?
指针是一个存储另一个变量地址的变量。要声明一个指针变量,它的名称前面加上 * 符号。指针变量的类型及其宿主变量的类型必须相同。
A pointer is a variable that stores the address of another variable. To declare a pointer variable, its name is prefixed with the * symbol. The type of the pointer variable and its host variable must be same.
地址分配给 & 运算符。 dereference operator ( )* 与指针一起使用。它获取地址分配给指针的变量的值。
The address is assigned with the & operator. The dereference operator ()* is used with the pointer. It fetches the value of a variable whose address is assigned to the pointer.
Example
以下示例演示了如何在 C 中进行引用和解引用 −
The following example demonstrates how referening and dereferencing work in C −
#include <stdio.h>
int main(){
int x = 10;
int *y = &x;
printf("x: %d Address of x: %d\n", x, &x);
printf("Address of y: %d \n", &y);
printf("Value at address in y: %d\n", *y);
}
运行代码并检查其输出:
Run the code and check its output −
x: 10 Address of x: -1742755108
Address of y: -1742755104
Value at address in y: 10
How Does Call by Reference Work in C?
当按引用调用函数时,将传递实际参数变量的地址,而不是它们的值。
When a function is called by reference, the address of the actual argument variables passed, instead of their values.
让我们定义一个接收两个变量的引用作为参数的 add()
函数 −
Let us define the add() function that receives the references of two variables −
int add(int *x, int *y){
int z = *x + *y;
return z;
}
当调用此函数时,会传递实际参数的地址。
When such a function is called, we pass the address of the actual argument.
Example
让我们从 main()
函数的内部通过引用调用 add()
函数 −
Let us call the add() function by reference from inside the main() function −
#include <stdio.h>
/* function declaration */
int add(int *, int *);
int main(){
int a = 10, b = 20;
int c = add(&a, &b);
printf("Addition: %d", c);
}
int add(int *x, int *y){
int z = *x + *y;
return z;
}
当你运行这段代码时,它将产生以下输出:
When you run this code, it will produce the following output −
Addition: 30
现在让我们了解此代码的实际工作原理。 main()
函数将 @s0
和 @s1
的地址传递给 @s2
函数。 @s3
和 @s4
的地址被分配给指针变量 @s5
和 @s6
。
Now let’s understand how this code actually works. The main() function passes the address of a and b to the add() function. The addresses of a and b are assigned to the pointer variables x and y.
现在关注语句 "z = @s7" 存储 @s8
的地址。 @s9
和 @s10
中的解引用运算符分别获取 @s11
和 @s12
的值,因此 @s13
是 main()
函数中 @s14
和 @s15
的和。
Now focus on the statement "z = x + *y;" inside the add() function. Remember that *x stores the address of a. The dereference operator in x and y fetches the values of a and b respectively, hence z is the addition of a and b in the main() function.
Example: Swap Values with Call by Reference
让我们在以下交换两个变量值的示例的帮助下,更详细地了解按引用调用机制如何工作。
Let us understand in more detail how the Call by Reference mechanism works, with the help of the following example that interchanges value of two variables.
#include <stdio.h>
/* Function definition to swap the values */
/* It receives the reference of two variables whose values are to be swapped */
int swap(int *x, int *y){
int z;
z = *x; /* save the value at address x */
*x = *y; /* put y into x */
*y = z; /* put z into y */
return 0;
}
/* The main() function has two variables "a" and "b" */
/* Their addresses are passed as arguments to the swap() function. */
int main(){
/* local variable definition */
int a = 10;
int b = 20;
printf("Before swap, value of a: %d\n", a );
printf("Before swap, value of b: %d\n", b );
/* calling a function to swap the values */
swap(&a, &b);
printf("After swap, value of a: %d\n", a);
printf("After swap, value of b: %d\n", b);
return 0;
}
当你运行这段代码时,它将产生以下输出:
When you run this code, it will produce the following output −
Before swap, value of a: 10
Before swap, value of b: 20
After swap, value of a: 20
After swap, value of b: 10
Explanation
假设 main()
函数中的变量 @s16
和 @s17
被分配了内存地址为 100 和 200 的位置。当它们的地址传递给 @s18
和 @s19
(请记住,它们是指针)时,swap() 函数中的变量 @s20
、 @s21
和 @s22
分别被创建于地址 1000、2000 和 3000。
Assume that the variables a and b in the main() function are allotted locations with the memory address 100 and 200 respectively. As their addresses are passed to x and y (remember that they are pointers), the variables x, y and z in the swap() function are created at addresses 1000, 2000 and 3000 respectively.

由于 "x" 和 "y" 存储 "a" 和 "b" 的地址,正如上图所示,因此 "x" 变为 100,而 "y" 变为 200。
Since "x" and "y" store the address of "a" and "b", "x" becomes 100 and "y" becomes 200, as the above figure shows.
在 swap()
函数内部,第一条语句 @s23
使地址存储在 "x" 中的值存储在 "x" 中(值为 10)。类似地,在语句 @s24
中,地址存储在 "y" 中的值(值为 20)存储在其指针为 "x" 的位置。
Inside the swap() function, the first statement "z = *x" causes the value at address in "x" to be stored in "x" (which is 10). Similarly, in the statement "*x = *y;", the value at the address in "y" (which is 20) is stored in the location whose pointer is "x".
最后,语句 @s25
将 "z" 分配给由 "y" 指向的变量,即 main()
函数中的 "b"。现在 "a" 和 "b" 的值发生了交换。
Finally, the statement "*y = z;" assigns the "z" to the variable pointed to by "y", which is "b" in the main() function. The values of "a" and "b" now get swapped.
下图直观地展示了其工作原理 −
The following figure visually demonstrates how it works −

Mixing Call by Value and Call by Reference
你可以使用按值调用和按引用调用相结合的函数调用机制。它可以被称为“混合调用机制”,其中一些参数按值传递,而另一些参数按引用传递。
You can use a function calling mechanism that is a combination of Call by Value and Call by Reference. It can be termed as "mixed calling mechanism", where some of the arguments are passed by value and others by reference.
C 中的函数可以有多个参数,但只能返回一个值。按引用调用机制是克服此限制的一个很好的解决方案。
A function in C can have more than one arguments, but can return only one value. The Call by Reference mechanism is a good solution to overcome this restriction.
Example
在这个示例中, calculate()
函数通过值接收一个整型参数,通过两个指针存储其平方和立方。
In this example, the calculate() function receives an integer argument by value, and two pointers where its square and cube are stored.
#include <stdio.h>
#include <math.h>
/* function declaration */
int calculate(int, int *, int *);
int main(){
int a = 10;
int b, c;
calculate(a, &b, &c);
printf("a: %d \nSquare of a: %d \nCube of a: %d", a, b, c);
}
int calculate(int x, int *y, int *z){
*y = pow(x,2);
*z = pow(x, 3);
return 0;
}
当你运行这段代码时,它将产生以下输出:
When you run this code, it will produce the following output −
a: 10
Square of a: 100
Cube of a: 1000
当函数需要执行内存级别的操作(例如控制外围设备、执行动态分配等)时,按引用调用机制被广泛使用。
The Call by Reference mechanism is widely used when a function needs to perform memory-level manipulations such as controlling the peripheral devices, performing dynamic allocation, etc.