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

news2025/2/11 0:00:45

在这里插入图片描述

博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳]
本文专栏: C语言

文章目录

  • 💯前言
  • 💯传值调用
    • 1. 什么是传值调用?
    • 2. 示例代码:传值调用失败的情况
      • 执行结果:
    • 3. 为什么传值调用无法修改外部变量?
  • 💯传址调用
    • 1. 什么是传址调用?
    • 2. 示例代码:传址调用成功的情况
      • 执行结果:
    • 3. 为什么传址调用能够修改外部变量?
  • 💯传值调用与传址调用的比较
    • 1. 传值调用的优缺点:
    • 2. 传址调用的优缺点:
  • 💯传值调用与传址调用的应用场景
  • 💯小结

在这里插入图片描述


在这里插入图片描述


💯前言

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

💯传值调用

1. 什么是传值调用?

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

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

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

#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 函数内部,参数 xy 仅仅是 ab 的副本。函数内对 xy 的交换操作不会影响到 main 函数中的 ab
  • 因为传入的是参数的副本,main 函数中的 ab 的值没有改变。

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

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

💯传址调用

1. 什么是传址调用?

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

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

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

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

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

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

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

1. 传值调用的优缺点:

优点:

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

缺点:

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

2. 传址调用的优缺点:

优点:

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

缺点:

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

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

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

💯小结

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

  • 传值调用将参数的副本传递给函数,适用于不需要修改外部变量的情况。
  • 传址调用则通过传递地址,使得函数能够直接修改外部变量,适用于需要修改变量的场景,尤其是在处理大数据时更为高效。

希望通过本文的讲解,你能对这两种参数传递方式有一个清晰的认识,并能够在实际编程中灵活应用。如果你有其他问题或需要进一步的解释,欢迎随时向我提问!


在这里插入图片描述


在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

另外,实际编程经验对于加深理解至关重要。通过编写简单的程序(例如`计算器`、`猜数字游戏`、`排序算法`等),你可以巩固所学的理论知识。随着技能的提升,尝试实现更复杂的功能,甚至学习一些经典的数据结构与算法,如链表、栈、队列等。解决实际问题会帮助你更好地理解C语言的各种特性。阅读经典书籍如《C程序设计语言》(K&R)是学习C语言的好方法。这本书不仅详细讲解了C语言的基本语法,还介绍了C语言的内存管理和底层实现,适合初学者和有经验的程序员。最后,学习C语言需要保持**耐心**和**持之以恒**的态度。它可能比其他高级编程语言更加底层、难度更高,但正是这种深入底层的学习使得你能够更好地理解计算机的运行机制,从而成为一名更出色的程序员。阅读经典书籍如《C程序设计语言》(K&R)是学习C语言的好方法。这本书不仅详细讲解了C语言的基本语法,还介绍了C语言的内存管理和底层实现,适合初学者和有经验的程序员。**学习C语言**是每个程序员成长道路上的一大步。C语言不仅为许多其他高级语言提供了基础,还帮助我们更深入地理解计算机如何工作。下面是一些建议,可以帮助你更好地学习C语言。首先,掌握C语言的**基础**非常重要。你需要理解变量的声明、数据类型的使用、常见的运算符(如算术运算符、关系运算符等)以及基本的输入输出函数(如`printf`和`scanf`)。这些是任何程序的构建模块,也是深入学习其他高级特性(如指针和内存管理)的基础。其次,学习**指针**是C语言中的关键环节。指针是C语言强大功能的核心,它直接与内存操作相关。你需要理解指针的基本概念,如指针变量、指针与数组的关系、指针运算等。尤其是在处理动态内存分配、数组和字符串时,指针能够极大提升程序的性能和灵活性。通过动手实现一些指针相关的练习,逐步消除对指针的恐惧感。另外,实际编程经验对于加深理解至关重要。通过编写简单的程序(例如`计算器`、`猜数字游戏`、`排序算法`等),你可以巩固所学的理论知识。随着技能的提升,尝试实现更复杂的功能,甚至学习一些经典的数据结构与算法,如链表、栈、队列等。解决实际问题会帮助你更好地理解C语言的各种特性。阅读经典书籍如《C程序设计语言》(K&R)是学习C语言的好方法。这本书不仅详细讲解了C语言的基本语法,还介绍了C语言的内存管理和底层实现,适合初学者和有经验的程序员。最后,学习C语言需要保持**耐心**和**持之以恒**的态度。它可能比其他高级编程语言更加底层、难度更高,但正是这种深入底层的学习使得你能够更好地理解计算机的运行机制,从而成为一名更出色的程序员。阅读经典书籍如《C程序设计语言》(K&R)是学习C语言的好方法。这本书不仅详细讲解了C语言的基本语法,还介绍了C语言的内存管理和底层实现,适合初学者和有经验的程序员。**学习C语言**是每个程序员成长道路上的一大步。C语言不仅为许多其他高级语言提供了基础,还帮助我们更深入地理解计算机如何工作。下面是一些建议,可以帮助你更好地学习C语言。首先,掌握C语言的**基础**非常重要。你需要理解变量的声明、数据类型的使用、常见的运算符(如算术运算符、关系运算符等)以及基本的输入输出函数(如`printf`和`scanf`)。这些是任何程序的构建模块,也是深入学习其他高级特性(如指针和内存管理)的基础。其次,学习**指针**是C语言中的关键环节。指针是C语言强大功能的核心,它直接与内存操作相关。你需要理解指针的基本概念,如指针变量、指针与数组的关系、指针运算等。尤其是在处理动态内存分配、数组和字符串时,指针能够极大提升程序的性能和灵活性。通过动手实现一些指针相关的练习,逐步消除对指针的恐惧感。另外,实际编程经验对于加深理解至关重要。通过编写简单的程序(例如`计算器`、`猜数字游戏`、`排序算法`等),你可以巩固所学的理论知识。随着技能的提升,尝试实现更复杂的功能,甚至学习一些经典的数据结构与算法,如链表、栈、队列等。解决实际问题会帮助你更好地理解C语言的各种特性。阅读经典书籍如《C程序设计语言》(K&R)是学习C语言的好方法。这本书不仅详细讲解了C语言的基本语法,还介绍了C语言的内存管理和底层实现,适合初学者和有经验的程序员。最后,学习C语言需要保持**耐心**和**持之以恒**的态度。它可能比其他高级编程语言更加底层、难度更高,但正是这种深入底层的学习使得你能够更好地理解计算机的运行机制,从而成为一名更出色的程序员阅读经典书籍如《C程序设计语言》(K&R)是学习C语言的好方法。这本书不仅详细讲解了C语言的基本语法,还介绍了C语言的内存管理和底层实现,适合初学者和有经验的程序员。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2296034.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

蓝桥杯C语言组:图论问题

蓝桥杯C语言组图论问题研究 摘要 图论是计算机科学中的一个重要分支&#xff0c;在蓝桥杯C语言组竞赛中&#xff0c;图论问题频繁出现&#xff0c;对参赛选手的算法设计和编程能力提出了较高要求。本文系统地介绍了图论的基本概念、常见算法及其在蓝桥杯C语言组中的应用&#…

windows通过网络向Ubuntu发送文件/目录

由于最近要使用树莓派进行一些代码练习&#xff0c;但是好多东西都在windows里或虚拟机上&#xff0c;就想将文件传输到树莓派上&#xff0c;但试了发现u盘不能简单传送&#xff0c;就在网络上找到了通过windows 的scp命令传送 前提是树莓派先开启ssh服务&#xff0c;且Window…

Unity抖音云启动测试:如何用cmd命令行启动exe

相关资料&#xff1a;弹幕云启动&#xff08;原“玩法云启动能力”&#xff09;_直播小玩法_抖音开放平台 1&#xff0c;操作方法 在做云启动的时候&#xff0c;接完发现需要命令行模拟云环境测试启动&#xff0c;所以研究了下。 首先进入cmd命令&#xff0c;CD进入对应包的文件…

ZU47DR 100G光纤 高性能板卡

简介 2347DR是一款最大可提供8路ADC接收和8路DAC发射通道的高性能板卡。板卡选用高性价比的Xilinx的Zynq UltraScale RFSoC系列中XCZU47DR-FFVE1156作为处理芯片&#xff08;管脚可以兼容XCZU48DR-FFVE1156&#xff0c;主要差别在有无FEC&#xff08;信道纠错编解码&#xff0…

【算法】动态规划专题⑥ —— 完全背包问题 python

目录 前置知识进入正题模板 前置知识 【算法】动态规划专题⑤ —— 0-1背包问题 滚动数组优化 完全背包问题是动态规划中的一种经典问题&#xff0c;它与0-1背包问题相似&#xff0c;但有一个关键的区别&#xff1a;在完全背包问题中&#xff0c;每种物品都有无限的数量可用。…

C#中深度解析BinaryFormatter序列化生成的二进制文件

C#中深度解析BinaryFormatter序列化生成的二进制文件 BinaryFormatter序列化时,对象必须有 可序列化特性[Serializable] 一.新建窗体测试程序BinaryDeepAnalysisDemo,将默认的Form1重命名为FormBinaryDeepAnalysis 二.新建测试类Test Test.cs源程序如下: using System; us…

51单片机之引脚图(详解)

8051单片机引脚分类与功能笔记 1. 电源引脚 VCC&#xff08;第40脚&#xff09;&#xff1a;接入5V电源&#xff0c;为单片机提供工作电压。GND&#xff08;第20脚&#xff09;&#xff1a;接地端&#xff0c;确保电路的电位参考点。 2.时钟引脚 XTAL1&#xff08;第19脚&a…

jupyterLab插件开发

jupyter lab安装、配置&#xff1a; jupyter lab安装、配置教程_容器里装jupyterlab-CSDN博客 『Linux笔记』服务器搭建神器JupyterLab_linux_布衣小张-腾讯云开发者社区 Jupyter Lab | 安装、配置、插件推荐、多用户使用教程-腾讯云开发者社区-腾讯云 jupyterLab插件开发教…

配置#include “nlohmann/json.hpp“,用于处理json文件

#include “nlohmann/json.hpp” // 需要安装 nlohmann/json.hpp 头文件 using json = nlohmann::json; 下载链接:https://github.com/nlohmann/json/tree/develop 1.下载并解压:首先,需要从nlohmann/json的GitHub仓库下载源代码,并解压得到的文件。 地址: nlohmann/json…

MATLAB | 基于Theil-Sen斜率和Mann-Kendall检验的栅格数据趋势分析

最近看到一些博主分享关于 SenMK 检验的代码&#xff0c;对于新手来说可能有点复杂。我们编写了一段 MATLAB 代码&#xff0c;能够一次性解决这些问题&#xff0c;简化操作流程。我们还准备了几个关于趋势检验的空间分布图&#xff0c;供大家参考。 一、Sens Slope和Mann-Kenda…

Windows 系统下使用 Ollama 离线部署 DeepSeek - R1 模型指南

引言 随着人工智能技术的飞速发展&#xff0c;各类大语言模型层出不穷。DeepSeek - R1 凭借其出色的语言理解和生成能力&#xff0c;受到了广泛关注。而 Ollama 作为一款便捷的模型管理和部署工具&#xff0c;能够帮助我们轻松地在本地环境中部署和使用模型。本文将详细介绍如…

Docker、Ollama、Dify 及 DeepSeek 安装配置与搭建企业级本地私有化知识库实践

在现代企业中&#xff0c;管理和快速访问知识库是提升工作效率、促进创新的关键。为了满足这些需求&#xff0c;企业越来越倾向于构建本地私有化的知识库系统&#xff0c;这样可以更好地保护企业数据的安全性和隐私性。本文将介绍如何利用 **Docker**、**Ollama**、**Dify** 和…

【漫话机器学习系列】087.常见的神经网络最优化算法(Common Optimizers Of Neural Nets)

常见的神经网络优化算法 1. 引言 在深度学习中&#xff0c;优化算法&#xff08;Optimizers&#xff09;用于更新神经网络的权重&#xff0c;以最小化损失函数&#xff08;Loss Function&#xff09;。一个高效的优化算法可以加速训练过程&#xff0c;并提高模型的性能和稳定…

【JVM详解四】执行引擎

一、概述 Java程序运行时&#xff0c;JVM会加载.class字节码文件&#xff0c;但是字节码并不能直接运行在操作系统之上&#xff0c;而JVM中的执行引擎就是负责将字节码转化为对应平台的机器码让CPU运行的组件。 执行引擎是JVM核心的组成部分之一。可以把JVM架构分成三部分&am…

route 与 router 之间的差别

简述&#xff1a; router&#xff1a;主要用于处理一些动作&#xff0c; route&#xff1a;主要获得或处理一些数据&#xff0c;比如地址、参数等 例&#xff1a; videoInfo1.vue&#xff1a; <template><div class"video-info"><h3>二级组件…

SamWaf开源轻量级的网站应用防火墙(安装包),私有化部署,加密本地存储的数据,易于启动,并支持 Linux 和 Windows 64 位和 Arm64

一、SamWaf轻量级开源防火墙介绍 &#xff08;文末提供下载&#xff09; SamWaf网站防火墙是一款适用于小公司、工作室和个人网站的开源轻量级网站防火墙&#xff0c;完全私有化部署&#xff0c;数据加密且仅保存本地&#xff0c;一键启动&#xff0c;支持Linux&#xff0c;Wi…

极客说|利用 Azure AI Agent Service 创建自定义 VS Code Chat participant

作者&#xff1a;卢建晖 - 微软高级云技术布道师 「极客说」 是一档专注 AI 时代开发者分享的专栏&#xff0c;我们邀请来自微软以及技术社区专家&#xff0c;带来最前沿的技术干货与实践经验。在这里&#xff0c;您将看到深度教程、最佳实践和创新解决方案。关注「极客说」&a…

windows + visual studio 2019 使用cmake 编译构建静、动态库并调用详解

环境 windows visual studio 2019 visual studio 2019创建cmake工程 1. 静态库.lib 1.1 静态库编译生成 以下是我创建的cmake工程文件结构&#xff0c;只关注高亮文件夹部分 libout 存放编译生成的.lib文件libsrc 存放编译用的源代码和头文件CMakeLists.txt 此次编译CMak…

【kafka实战】05 Kafka消费者消费消息过程源码剖析

1. 概述 Kafka消费者&#xff08;Consumer&#xff09;是Kafka系统中负责从Kafka集群中拉取消息的客户端组件。消费者消费消息的过程涉及多个步骤&#xff0c;包括消费者组的协调、分区分配、消息拉取、消息处理等。本文将深入剖析Kafka消费者消费消息的源码&#xff0c;并结合…

[EAI-033] SFT 记忆,RL 泛化,LLM和VLM的消融研究

Paper Card 论文标题&#xff1a;SFT Memorizes, RL Generalizes: A Comparative Study of Foundation Model Post-training 论文作者&#xff1a;Tianzhe Chu, Yuexiang Zhai, Jihan Yang, Shengbang Tong, Saining Xie, Dale Schuurmans, Quoc V. Le, Sergey Levine, Yi Ma 论…