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

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

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

💯传值调用
1. 什么是传值调用?
传值调用是C语言中最常见的函数参数传递方式。在这种方式下,函数接收到的是参数的副本。换句话说,函数在调用时并不会修改原始参数,而是对参数的副本进行操作。
2. 示例代码:传值调用失败的情况
假设我们有一个函数 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的值没有改变。
3. 为什么传值调用无法修改外部变量?
传值调用的核心问题是,它将参数的副本传递给函数,而不是变量本身。这意味着函数对副本所做的任何修改都不会影响外部变量。在上面的代码中,a 和 b 被传递给了 Swap 函数的副本 x 和 y,即使 x 和 y 的值发生了交换,外部的 a 和 b 仍然保持不变。
💯传址调用
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函数通过传递a和b的地址,获得了指向a和b的指针(即px和py)。通过解引用这些指针,函数能够直接修改a和b的值。 - 在
Swap2函数内部,交换操作成功影响了main函数中的a和b。
3. 为什么传址调用能够修改外部变量?
传址调用通过传递参数的地址,使得函数能够直接操作外部变量。由于 Swap2 函数接受的是 a 和 b 的指针,函数内部通过指针解引用修改了 a 和 b 的值。这种修改是直接作用于原始变量的,而不是它们的副本。因此,外部变量的值得以改变。
💯传值调用与传址调用的比较
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语言的内存管理和底层实现,适合初学者和有经验的程序员。
相关文章:
【C语言】传值调用与传址调用详解
博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C语言 文章目录 💯前言💯传值调用1. 什么是传值调用?2. 示例代码:传值调用失败的情况执行结果: 3. 为什么传值调用无法修改外部变量? Ǵ…...
蓝桥杯C语言组:图论问题
蓝桥杯C语言组图论问题研究 摘要 图论是计算机科学中的一个重要分支,在蓝桥杯C语言组竞赛中,图论问题频繁出现,对参赛选手的算法设计和编程能力提出了较高要求。本文系统地介绍了图论的基本概念、常见算法及其在蓝桥杯C语言组中的应用&#…...
windows通过网络向Ubuntu发送文件/目录
由于最近要使用树莓派进行一些代码练习,但是好多东西都在windows里或虚拟机上,就想将文件传输到树莓派上,但试了发现u盘不能简单传送,就在网络上找到了通过windows 的scp命令传送 前提是树莓派先开启ssh服务,且Window…...
Unity抖音云启动测试:如何用cmd命令行启动exe
相关资料:弹幕云启动(原“玩法云启动能力”)_直播小玩法_抖音开放平台 1,操作方法 在做云启动的时候,接完发现需要命令行模拟云环境测试启动,所以研究了下。 首先进入cmd命令,CD进入对应包的文件…...
ZU47DR 100G光纤 高性能板卡
简介 2347DR是一款最大可提供8路ADC接收和8路DAC发射通道的高性能板卡。板卡选用高性价比的Xilinx的Zynq UltraScale RFSoC系列中XCZU47DR-FFVE1156作为处理芯片(管脚可以兼容XCZU48DR-FFVE1156,主要差别在有无FEC(信道纠错编解码࿰…...
【算法】动态规划专题⑥ —— 完全背包问题 python
目录 前置知识进入正题模板 前置知识 【算法】动态规划专题⑤ —— 0-1背包问题 滚动数组优化 完全背包问题是动态规划中的一种经典问题,它与0-1背包问题相似,但有一个关键的区别:在完全背包问题中,每种物品都有无限的数量可用。…...
MySQL——表操作及查询
一.表操作 MySQL的操作中,一些专用的词无论是大写还是小写都是可以通过的。 1.插入数据 INSERT [INTO] table_name (列名称…)VALUES (列数据…), (列数据…); "[]"表示可有可无,插入时,如果不指定要插入的列,则表示默…...
SAP-ABAP:ROLLBACK WORK使用详解
在SAP ABAP 中,ROLLBACK WORK 语句用于回滚当前事务(LUW,Logical Unit of Work),撤销自上次提交或回滚以来的所有数据库更改。它通常与 COMMIT WORK 配合使用,确保数据一致性。 关键点: 回滚作…...
C#中深度解析BinaryFormatter序列化生成的二进制文件
C#中深度解析BinaryFormatter序列化生成的二进制文件 BinaryFormatter序列化时,对象必须有 可序列化特性[Serializable] 一.新建窗体测试程序BinaryDeepAnalysisDemo,将默认的Form1重命名为FormBinaryDeepAnalysis 二.新建测试类Test Test.cs源程序如下: using System; us…...
Git提交错误解决:missing Change-Id in message footer
问题现象: 提交的commit中没有插入change id导致push代码失败。 问题解决: 针对该错误,Git已经给出了解决方案: 1、to automatically insert a Change-Id, install the hook: gitdir$(git rev-parse --git-dir); scp -p -P 2…...
51单片机之引脚图(详解)
8051单片机引脚分类与功能笔记 1. 电源引脚 VCC(第40脚):接入5V电源,为单片机提供工作电压。GND(第20脚):接地端,确保电路的电位参考点。 2.时钟引脚 XTAL1(第19脚&a…...
jupyterLab插件开发
jupyter lab安装、配置: 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 检验的代码,对于新手来说可能有点复杂。我们编写了一段 MATLAB 代码,能够一次性解决这些问题,简化操作流程。我们还准备了几个关于趋势检验的空间分布图,供大家参考。 一、Sens Slope和Mann-Kenda…...
python连点器
要实现一个用于抖音点赞的鼠标连点工具,可以通过编程或现有软件实现。以下是两种常见方法(但请注意:频繁自动化操作可能违反平台规则,需谨慎使用): 方法 1:使用现成工具(如 AutoClic…...
C#程式状态机及其Godot实践
前言 今天是周日,马上就要迎来新的一周了,前几周都没干什么事,为了减缓偷懒症状,立个Flag从今往后每周至少更新两次文章。内容虽然无法保证优质,但重在坚持,全当写周记了。希望不要三分钟热度吧。 今天记录…...
Windows 系统下使用 Ollama 离线部署 DeepSeek - R1 模型指南
引言 随着人工智能技术的飞速发展,各类大语言模型层出不穷。DeepSeek - R1 凭借其出色的语言理解和生成能力,受到了广泛关注。而 Ollama 作为一款便捷的模型管理和部署工具,能够帮助我们轻松地在本地环境中部署和使用模型。本文将详细介绍如…...
Docker、Ollama、Dify 及 DeepSeek 安装配置与搭建企业级本地私有化知识库实践
在现代企业中,管理和快速访问知识库是提升工作效率、促进创新的关键。为了满足这些需求,企业越来越倾向于构建本地私有化的知识库系统,这样可以更好地保护企业数据的安全性和隐私性。本文将介绍如何利用 **Docker**、**Ollama**、**Dify** 和…...
【漫话机器学习系列】087.常见的神经网络最优化算法(Common Optimizers Of Neural Nets)
常见的神经网络优化算法 1. 引言 在深度学习中,优化算法(Optimizers)用于更新神经网络的权重,以最小化损失函数(Loss Function)。一个高效的优化算法可以加速训练过程,并提高模型的性能和稳定…...
react-native fetch在具有http远程服务器后端的Android设备上抛出“Network request failed“错误
问题描述: 在具有http远程服务器后端的Android设备上,使用react-native fetch时抛出"Network request failed"错误。 回答: "Network request failed"错误通常表示在进行网络请求时出现了问题。可能的原因包括网络连接…...
【JVM详解四】执行引擎
一、概述 Java程序运行时,JVM会加载.class字节码文件,但是字节码并不能直接运行在操作系统之上,而JVM中的执行引擎就是负责将字节码转化为对应平台的机器码让CPU运行的组件。 执行引擎是JVM核心的组成部分之一。可以把JVM架构分成三部分&am…...
route 与 router 之间的差别
简述: router:主要用于处理一些动作, route:主要获得或处理一些数据,比如地址、参数等 例: videoInfo1.vue: <template><div class"video-info"><h3>二级组件…...
[vue3] Ref Reactive
【b站-【前端面试】Vue3 ref 与 reactive 区别】 Ref:Ref用于创建一个响应式的基本数据类型,比如数字、字符串等。它将普通的数据变成响应式数据,可以监听数据的变化。使用Ref时,我们可以通过.value来访问和修改数据的值。 Reac…...
SamWaf开源轻量级的网站应用防火墙(安装包),私有化部署,加密本地存储的数据,易于启动,并支持 Linux 和 Windows 64 位和 Arm64
一、SamWaf轻量级开源防火墙介绍 (文末提供下载) SamWaf网站防火墙是一款适用于小公司、工作室和个人网站的开源轻量级网站防火墙,完全私有化部署,数据加密且仅保存本地,一键启动,支持Linux,Wi…...
极客说|利用 Azure AI Agent Service 创建自定义 VS Code Chat participant
作者:卢建晖 - 微软高级云技术布道师 「极客说」 是一档专注 AI 时代开发者分享的专栏,我们邀请来自微软以及技术社区专家,带来最前沿的技术干货与实践经验。在这里,您将看到深度教程、最佳实践和创新解决方案。关注「极客说」&a…...
22.2、Apache安全分析与增强
目录 Apache Web安全分析与增强 - Apache Web概述Apache Web安全分析与增强 - Apache Web安全威胁Apache Web安全机制Apache Web安全增强 Apache Web安全分析与增强 - Apache Web概述 阿帕奇是一个用于搭建WEB服务器的应用程序,它是开源的,它的配置文件…...
理邦仪器嵌入式(C/C++开发)开发面试题及参考答案
C++ 虚函数的概念和作用 C++ 中的虚函数是一种非常重要的机制,它在实现多态性方面起着关键作用。 概念上来说,虚函数是在基类中使用关键字 virtual 声明的成员函数。当基类的指针或引用指向派生类的对象时,通过这个基类的指针或引用调用虚函数,实际执行的是派生类中重写的该…...
windows + visual studio 2019 使用cmake 编译构建静、动态库并调用详解
环境 windows visual studio 2019 visual studio 2019创建cmake工程 1. 静态库.lib 1.1 静态库编译生成 以下是我创建的cmake工程文件结构,只关注高亮文件夹部分 libout 存放编译生成的.lib文件libsrc 存放编译用的源代码和头文件CMakeLists.txt 此次编译CMak…...
Chrome 浏览器 支持多账号登录和管理的浏览器容器解决方案
根据搜索结果,目前没有直接提到名为“chrometable”的浏览器容器或插件。不过,从功能描述来看,您可能需要的是一个能够支持多账号登录和管理的浏览器容器解决方案。以下是一些可能的实现方式: 1. 使用 Docker 容器化部署 Chrome …...
GrassWebProxy
GrassWebProxy第一版: using System; using System.Collections.Generic; using System.Linq; using System.Net.Sockets; using System.Net; using System.Text; using System.Threading; using System.Threading.Tasks; using System.IO; using Newtonsoft.Json;…...
