前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >【C语言】传值调用与传址调用详解

【C语言】传值调用与传址调用详解

作者头像
CSDN-Z
发布2025-02-08 13:44:02
发布2025-02-08 13:44:02
11300
代码可运行
举报
文章被收录于专栏:AIGCAIGC
运行总次数:0
代码可运行

💯前言

  • 在C语言的学习过程中,理解函数的参数传递方式是非常重要的概念。C语言支持两种常见的参数传递方式:传值调用(Call by Value)和传址调用(Call by Address)。这两种方式在程序中有着不同的行为和应用场景,因此掌握它们的差异和用法对于编写高效、正确的代码至关重要。本文将详细分析这两种参数传递方式,并通过代码示例帮助读者深入理解。 在C语言中,函数在被调用时会接收参数。参数传递是指在函数调用时,函数的输入数据(参数)如何从调用者传递到被调用的函数。传值调用和传址调用是两种常见的传递方式,它们的差别决定了函数能否改变传入参数的值。传值调用会将参数的副本传递给函数,而传址调用则将参数的地址传递给函数,从而使得函数可以直接修改原始参数。 本文将通过代码示例和图示,详细分析这两种参数传递方式的工作原理,并探讨它们的优缺点和应用场景。 C语言
在这里插入图片描述
在这里插入图片描述

💯传值调用

1. 什么是传值调用?

传值调用是C语言中最常见的函数参数传递方式。在这种方式下,函数接收到的是参数的副本。换句话说,函数在调用时并不会修改原始参数,而是对参数的副本进行操作。

2. 示例代码:传值调用失败的情况

假设我们有一个函数 Swap,用于交换两个整数的值。在传值调用的情况下,我们尝试交换两个变量 ab

代码语言:javascript
代码运行次数:0
复制
#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;
}
执行结果:
代码语言:javascript
代码运行次数:0
复制
交换前: a=10 b=20
交换后: a=10 b=20

分析:

  • Swap 函数内部,参数 xy 仅仅是 ab 的副本。函数内对 xy 的交换操作不会影响到 main 函数中的 ab
  • 因为传入的是参数的副本,main 函数中的 ab 的值没有改变。

3. 为什么传值调用无法修改外部变量?

传值调用的核心问题是,它将参数的副本传递给函数,而不是变量本身。这意味着函数对副本所做的任何修改都不会影响外部变量。在上面的代码中,ab 被传递给了 Swap 函数的副本 xy,即使 xy 的值发生了交换,外部的 ab 仍然保持不变。

💯传址调用

1. 什么是传址调用?

与传值调用不同,传址调用会将变量的地址传递给函数,这样函数就能够直接修改原始变量的值。在传址调用中,传递的是变量的指针,函数通过指针访问并修改原始变量的内容。

2. 示例代码:传址调用成功的情况

下面是使用传址调用成功交换变量值的例子:

代码语言:javascript
代码运行次数:0
复制
#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;
}
执行结果:
代码语言:javascript
代码运行次数:0
复制
交换前: a=10 b=20
交换后: a=20 b=10

分析:

  • 这一次,Swap2 函数通过传递 ab 的地址,获得了指向 ab 的指针(即 pxpy)。通过解引用这些指针,函数能够直接修改 ab 的值。
  • Swap2 函数内部,交换操作成功影响了 main 函数中的 ab

3. 为什么传址调用能够修改外部变量?

传址调用通过传递参数的地址,使得函数能够直接操作外部变量。由于 Swap2 函数接受的是 ab 的指针,函数内部通过指针解引用修改了 ab 的值。这种修改是直接作用于原始变量的,而不是它们的副本。因此,外部变量的值得以改变。

💯传值调用与传址调用的比较

1. 传值调用的优缺点:

优点:

  • 安全性较高,因为函数内部不会直接修改外部变量的值。
  • 当参数较小且不需要在函数内部修改时,传值调用是更合适的选择。

缺点:

  • 传递大数据(如大数组或结构体)时会产生较大的内存开销,因为函数接收的是参数的副本。

2. 传址调用的优缺点:

优点:

  • 通过传递指针,可以直接修改外部变量,适用于需要在函数内修改外部变量的场景。
  • 对于大数据(如数组、结构体等),传址调用比传值调用更高效,因为不需要复制大量的数据。

缺点:

  • 由于函数可以修改外部变量,可能会带来一定的副作用,因此需要小心使用。
  • 指针操作相对复杂,可能导致指针悬挂、内存泄漏等问题。

💯传值调用与传址调用的应用场景

  • 传值调用:当函数不需要修改传入的参数,或者当参数是小型数据(如整数、浮点数等)时,传值调用是最常见且安全的选择。
  • 传址调用:当需要修改传入的参数,或者当参数较大(如数组、结构体等)时,传址调用更为高效。

💯小结

通过上述分析,我们深入探讨了C语言中两种常见的参数传递方式:传值调用传址调用。我们通过代码示例展示了它们在实际使用中的不同表现,并详细解释了它们的优缺点和应用场景。

  • 传值调用将参数的副本传递给函数,适用于不需要修改外部变量的情况。
  • 传址调用则通过传递地址,使得函数能够直接修改外部变量,适用于需要修改变量的场景,尤其是在处理大数据时更为高效。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-02-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 💯前言
  • 💯传值调用
    • 1. 什么是传值调用?
    • 2. 示例代码:传值调用失败的情况
      • 执行结果:
    • 3. 为什么传值调用无法修改外部变量?
  • 💯传址调用
    • 1. 什么是传址调用?
    • 2. 示例代码:传址调用成功的情况
      • 执行结果:
    • 3. 为什么传址调用能够修改外部变量?
  • 💯传值调用与传址调用的比较
    • 1. 传值调用的优缺点:
    • 2. 传址调用的优缺点:
  • 💯传值调用与传址调用的应用场景
  • 💯小结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档