Cprogramming 简明教程

Function Call by Value in C

在 C 语言中,可以从任何其他函数(包括自身)调用函数。有两种方法可以调用函数:(a) 按值调用和 (b) 按引用调用。默认情况下,使用按值调用机制。

Formal Arguments and Actual Arguments

您必须了解术语才能了解按值调用方法是如何工作的:

Formal arguments - 函数需要某些数据来执行其所需的进程。定义函数时,假定数据值将以参数或参数列表的形式提供,该列表位于函数名称前面的括号中。这些参数是某个数据类型的变量。

Actual arguments - 当要调用某个函数时,它应该提供所需数量的值,其类型与在函数定义中使用的类型相同,并且按相同的顺序提供。

看一看以下片段:

type function_name(type var1, type var2, ...)

这里,参数变量被称为 formal arguments 。在函数的作用域内,这些变量作为其 local variables

考虑以下函数:

int add(int x, int y){

   int z = x + y;

   return z;

}

此函数定义中的参数 xy 是形式参数。

Example: Call by Value in C

如果调用了 add() 函数,如下面的代码所示,那么括号内的变量 ( ab ) 是实际参数。它们被传递给函数。

请看以下示例:

#include <stdio.h>

int add(int x, int y){

   int z = x + y;

   return z;
}

int main(){

   int a = 10, b = 20;

   int c = add(a, b);

   printf("Addition: %d", c);
}

当你运行这段代码时,它将产生以下输出:

Addition: 30

按值传递方法表示实际参数的值被复制到形式参数变量中。因此,“x”取“a”的值,而“y”被赋值给“b”。add() 函数内部的局部变量“z”存储加法值。在 main() 函数中,由 add() 函数返回的值被赋值给“c”,然后打印出来。

请注意,C 语言中的变量是内存中的一个命名位置。因此,变量在内存中创建,并且编译器为每个变量分配一个随机内存地址。

How Does "Call by Value" Work in C?

让我们假设 main() 函数中的变量 abc 分别占据内存位置 100、200 和 300。当使用 ab 作为实际参数调用 add() 函数时,它们的值分别存储在 xy 中。

random memory address

变量 xyz 是 add() 函数的局部变量。在内存中,将为它们分配一些随机位置。我们假设它们分别在内存地址 1000、2000 和 3000 中创建。

由于函数通过将实际参数的值复制到其相应的形式参数变量来调用,因此 xy 的地址 1000 和 2000 分别容纳 10 和 20。编译器将它们的加法赋值给他们返回的第三个局部变量 z

当控制权返回 main() 函数时,返回的数据被赋值给 c ,并显示为程序的输出。

Example

按值传递是 C 语言中的默认函数调用机制。它消除了函数的潜在副作用,使你的软件更容易维护和理解。它最适合于期望对接收到的参数执行特定计算并返回结果的函数。

以下按值传递的另一个示例:

#include <stdio.h>

/* function declaration */
void swap(int x, int y);

int main(){

   /* local variable definition */
   int a = 100;
   int b = 200;

   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;
}

void swap(int x, int y){

   int temp;

   temp = x; /* save the value of x */
   x = y;    /* put y into x */
   y = temp; /* put temp into y */

   return;
}

当你运行这段代码时,它将产生以下输出:

Before swap, value of a: 100
Before swap, value of b: 200
After swap, value of a: 100
After swap, value of b: 200

它表明值没有发生变化,尽管它们在函数内部发生改变。

由于值被复制到另一个函数的不同局部变量中,因此任何操作都不会对调用函数中的实际参数变量产生任何影响。

然而,当我们需要将大型对象(如数组或文件)传递给另一个函数时,按值传递方法的效率较低。另外,在某些情况下,我们可能需要另一个函数操作实际参数。在这些情况下,按值传递机制不起作用。我们必须为此目的探索按引用传递机制。请参阅下一章以获取有关 C 语言按引用传递机制的详细解释。

按引用传递方法涉及传递包含实际参数值的变量的地址。你可以设计一个调用方法,它是按值传递和按引用传递的混合。在这种情况下,一些参数按值传递,而另一些按引用传递。