传值调用是C语言中最常见的函数参数传递方式。在这种方式下,函数接收到的是参数的副本。换句话说,函数在调用时并不会修改原始参数,而是对参数的副本进行操作。
假设我们有一个函数 Swap
,用于交换两个整数的值。在传值调用的情况下,我们尝试交换两个变量 a
和 b
:
#include <stdio.h>
void Swap(int x, int y) {
int tmp = x;
x = y;
y = tmp;
}
int main() {
int a = 0;
int b = 0;
scanf("%d %d", &a, &b); // 用户输入两个整数
printf("交换前: a=%d b=%d
", a, b);
Swap(a, b); // 传值调用
printf("交换后: a=%d b=%d
", a, b); // a 和 b 的值未改变
return 0;
}
交换前: a=10 b=20
交换后: a=10 b=20
分析:
Swap
函数内部,参数 x
和 y
仅仅是 a
和 b
的副本。函数内对 x
和 y
的交换操作不会影响到 main
函数中的 a
和 b
。main
函数中的 a
和 b
的值没有改变。传值调用的核心问题是,它将参数的副本传递给函数,而不是变量本身。这意味着函数对副本所做的任何修改都不会影响外部变量。在上面的代码中,a
和 b
被传递给了 Swap
函数的副本 x
和 y
,即使 x
和 y
的值发生了交换,外部的 a
和 b
仍然保持不变。
与传值调用不同,传址调用会将变量的地址传递给函数,这样函数就能够直接修改原始变量的值。在传址调用中,传递的是变量的指针,函数通过指针访问并修改原始变量的内容。
下面是使用传址调用成功交换变量值的例子:
#include <stdio.h>
void Swap2(int *px, int *py) {
int tmp = *px; // 解引用指针,获取 px 指向的值
*px = *py; // 将 py 指向的值赋给 px 指向的变量
*py = tmp; // 将 tmp 的值赋给 py 指向的变量
}
int main() {
int a = 0;
int b = 0;
scanf("%d %d", &a, &b); // 用户输入两个整数
printf("交换前: a=%d b=%d
", a, b);
Swap2(&a, &b); // 传址调用,传递 a 和 b 的地址
printf("交换后: a=%d b=%d
", a, b); // a 和 b 的值会成功交换
return 0;
}
交换前: a=10 b=20
交换后: a=20 b=10
分析:
Swap2
函数通过传递 a
和 b
的地址,获得了指向 a
和 b
的指针(即 px
和 py
)。通过解引用这些指针,函数能够直接修改 a
和 b
的值。Swap2
函数内部,交换操作成功影响了 main
函数中的 a
和 b
。传址调用通过传递参数的地址,使得函数能够直接操作外部变量。由于 Swap2
函数接受的是 a
和 b
的指针,函数内部通过指针解引用修改了 a
和 b
的值。这种修改是直接作用于原始变量的,而不是它们的副本。因此,外部变量的值得以改变。
优点:
缺点:
优点:
缺点:
通过上述分析,我们深入探讨了C语言中两种常见的参数传递方式:传值调用和传址调用。我们通过代码示例展示了它们在实际使用中的不同表现,并详细解释了它们的优缺点和应用场景。