你知道C语言函数调用的2种方式吗?传值调用 传址调用

news2024/11/15 12:53:08

本篇博客会讲解C语言函数调用的2种方式,分别是:传值调用和传址调用。这2种函数调用方式有什么区别呢?为什么会有不同的效果呢?分别有哪些用途呢?下面我会一一展开。

在这里插入图片描述

区别

  1. 传值调用,即通过传递变量的值来调用函数。
  2. 传址调用,即通过传递变量的地址来调用函数。

比如,假设有2个变量a和b,对于变量a和b来说test(a, b)就是传值调用,test(&a, &b)就是传址调用。

原理

这时你可能很好奇:这2种调用方式的原理是什么呢?其实非常简单。

先举个传值调用的例子:

// 函数定义
int Add(int x, int y)
{
	return x + y;
}

// 调用
int a = 3, b = 5;
int sum = Add(a, b);

在上面的代码中,我们分别把a和b的值传递给了Add函数中的x和y。此时,我们称:a和b是“实际参数”,简称实参;x和y是“形式参数”,简称形参。传值调用的方式,会把实参的值传递给形参,也就是说,把a中的3传递给x,此时x就是3,把b中的5传递给y,此时y就是5。在Add函数内部,把x+y的值带回来,也就返回3+5的值,即返回8,再把返回值赋值给sum,sum就是8。

再举个传址调用的例子:

// 函数定义
int Add(int* p1, int* p2)
{
	return *p1 + *p2;
}

// 调用
int a = 3, b = 5;
int sum = Add(&a, &b);

以上就是典型的传址调用,但是很显然在这个场景下,我们只想“求和”,使用传址调用有点多此一举,但是还是分析一下原理:我们把a和b的地址传给了p1和p2,此时p1存储了a的地址,p2存储了b的地址,p1就指向了a,p2就指向了b。我们想在Add函数内部求和,就要先对p1解引用,拿到a的值,再对p2解引用,拿到b的值,再把拿到的a和b的值加起来返回,此时sum就被赋值为函数的返回值,即8。

以上只是非常粗略的带大家了解了传值调用和传址调用的区别。下面用一个经典的例子进行更加深入的讲解。这个例子就是:写一个函数,交换2个整数的值。

使用传值调用的方式,写出来的函数如下:

// 定义
void Swap(int x, int y)
{
	int tmp = x;
	x = y;
	y = tmp;
}

// 调用
int a = 3, b = 5;
Swap(a, b);

下面我通过调试的方式,来带大家看一下这个程序会如何执行。
在这里插入图片描述
代码即将执行Swap(a, b);,此时a的值是3,b的值是5。接下来执行这条语句:
在这里插入图片描述
代码来到第17行,此时a和b的值并没有交换?到底发生了啥?

重新开始调试,这次我进入到Swap函数内部看一眼。
在这里插入图片描述
按照前面的分析,此时x和y拿到了a和b的值,接下来进行交换:
在这里插入图片描述
代码执行到第10行,此时可以发现,x和y其实已经交换了,但是a和b并没有变化?这又是为什么呢?

此时再回到main函数,发现a和b的值并没有被交换。
在这里插入图片描述

发现这个问题后,我们可以干一件事,使用下面的代码,把a、b、x、y的地址打印出来:

#include <stdio.h>

void Swap(int x, int y)
{
	printf("&x = %p, &y = %p\n", &x, &y);
	int tmp = x;
	x = y;
	y = tmp;
}

int main()
{
	int a = 3, b = 5;
	printf("&a = %p, &b = %p\n", &a, &b);
	Swap(a, b);

	return 0;
}

输出结果如下:
在这里插入图片描述
可以发现,当把a的值传递给x,把b的值传递给y时,x和y,a和b已经是不同的空间了,此时相当于,内存中有4个变量,分别是a、b、x、y,由于值传递,x的值和a相同,y的值和b相同,此时交换了x和y,对a和b的值并没有影响!所以函数调用结束后,a和b的值并没有交换。

这时,我们就可以总结:当我们使用传值调用,实参的值传递给形参后,形参只是实参的一份临时拷贝,改变形参的值并不影响实参的值!

那Swap函数的正确实现形式是怎样的呢?相信聪明的你已经想到了,使用传址调用就行了嘛!

// 定义
void Swap(int* p1, int* p2)
{
	int tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}

// 调用
int a = 3, b = 5;
Swap(&a, &b);

为什么以上的代码就能实现“交换”的效果呢?这就是传址调用的神奇之处!

分析一下:把a的地址传递给p1,把b的地址传递给p2,此时p1就指向了a,p2就指向了b,这时再对p1和p2解引用,就能把a和b的值给修改了!

我们还是通过调试来观察一下细节:
在这里插入图片描述
进入到函数内部:
在这里插入图片描述
再回到main函数:
在这里插入图片描述
成功交换了a和b的值!

用途

根据以上的讲解,可以总结一下传值调用和传址调用的用途:

  1. 传值调用适用于不需要修改函数外部变量的场景。
  2. 传址调用适用于需要修改函数外部变量的场景。

这是因为,传值调用时,形参是实参的一份临时拷贝,改变形参并不影响实参,所以在函数内部没有能力改变外面的变量的值;传址调用就不一样了,形参保存了函数外部变量的地址,就可以通过解引用的方式,修改函数外部变量的值了。

总结

  1. 传值调用适用于不需要修改函数外部变量的场景,因为函数内部变量和外部变量并没有建立联系,是独立的空间。
  2. 传址调用适用于需要修改函数外部变量的场景,因为函数内部存储了指向函数外部变量的指针,建立了联系,可以通过解引用的方式改变函数外部的变量。

感谢大家的阅读!

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

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

相关文章

4个python内存性能检测工具:memory_profiler、timeit、line_profiler、heartrate的使用案例

这里总结了4个比较好的python性能检测工具&#xff0c;包括内存使用、运行时间、执行次数等方面。 1、memory_profiler查看内存的使用情况 memory_profiler可以用来测量python进程的内存使用情况。可以按行查看内存的使用情况。 memory_profiler 是一个监控进程内存消耗的模…

基于cv2的手势识别-计算机视觉

闲的无聊做的一个小玩意&#xff0c;可以调用你的计算机相机&#xff0c;识别框内的手势&#xff08;剪刀、石头和布&#xff09;&#xff0c;提供一个判决平台&#xff0c;感兴趣的可以继续完善。 用到的参考小文献&#xff1a; 具体实现结果如下 并且我另写了一个框架平台&…

风雨30年,电子表格惊人跨越,excel用户:表格都能生成软件了

电子表格&#xff0c;绝不是你看到的样子&#xff01; 你知道电子表格的前世今生吗&#xff1f; 它绝不只是你现在看到Excel或者WPS的模样。 不同的时代&#xff0c;有着不同的样子 DOS时代没有什么“可见可得”。什么都是靠想象力的&#xff0c;就是屏幕上文档的显示和打印…

供应商管理怎么做?供应商管理办法及流程介绍

阅读本文你将了解&#xff1a;1、供应商管理的重要性&#xff08;供应商管理的痛点&#xff09;&#xff1b;2、供应商管理具体流程&#xff1b;供应商管理系统有什么作用。 一、供应商管理的重要性&#xff08;供应商管理的痛点&#xff09; 供应商管理是组织中至关重要的一环…

锂溶液净化和提纯

锂离子电池是一种充电电池&#xff0c;依靠锂离子在正极和负极之间移动来工作&#xff0c;广泛应用在便携式设备、卫星、储备电源、电动汽车等领域&#xff0c;具有替代各种二次电源的潜力。 近年来国家大力提倡和发展的新能源产业&#xff0c;锂离子电池的需求量的不断攀升&a…

三维实景模型在线浏览平台,在线编辑、在线分享各类地理空间数据

很多行业用户在获取了大量的三维实景模型数据后&#xff0c;想要进行在线浏览或者分享给他人查看&#xff0c;以往只能通过人工手动将模型压缩&#xff0c;不但耗时费力&#xff0c;效果还难以达到预期。 其实&#xff0c;只需要通过四维轻云地理空间数据云管理平台就能轻松实…

DataX数据同步工具使用

1.DataX 简介 DataX 是阿里云 DataWorks 数据集成 的开源版本&#xff0c;主要就是用于实现数据间的离线同步。 DataX 致力于实现包括关系型数据库&#xff08;MySQL、Oracle 等&#xff09;、HDFS、Hive、ODPS、HBase、FTP 等 各种异构数据源&#xff08;即不同的数据库&…

# Linux shell终端设置代理服务器的方法

Linux shell终端设置代理服务器的方法 文章目录 Linux shell终端设置代理服务器的方法1 变量列表2 设置方法2.1 设置代理2.2 测试代理 3 软件专用代理3.1 yum专用代理3.2 git专用代理3.3 wget专用代理3.4 curl专用代理3.5 pip专用代理3.6 aria2c专用代理 4 最后 通过设置Linux变…

三个方法教你快速找到LinkedIn领英的潜在客户(置顶收藏)

第三点–最后一点是重点&#xff0c;要看到最后 相信很多外贸业务员都有这样的问题&#xff1a;“为什么你运营的账户询问的人数那么多&#xff0c;我自己运营的账户却没有人问呢&#xff1f;你是不是有什么好的运营技巧啊&#xff0c;可以给我说一下吗&#xff1f;”事实上&a…

Shell编程循环语句for while until(心有所觉,但亦做不解)

一、for 循环 1.用法和特点 读取不同的变量值&#xff0c;用来逐个执行同一组命令 for循环经常使用在已经知道要进行多少次循环的场景 for 变量 in 取值列表 -- 默认取值分割符&#xff08;空格、制表符、换行符&#xff09;do 或 {命令序列 done 或 }2.执行指…

时序预测 | Matlab实现SSA-BiLSTM、BiLSTM麻雀算法优化双向长短期记忆神经网络时间序列预测(含优化前后对比)

时序预测 | Matlab实现SSA-BiLSTM、BiLSTM麻雀算法优化双向长短期记忆神经网络时间序列预测(含优化前后对比) 目录 时序预测 | Matlab实现SSA-BiLSTM、BiLSTM麻雀算法优化双向长短期记忆神经网络时间序列预测(含优化前后对比)预测效果基本介绍程序设计参考资料 预测效果 基本介…

数学中为什么要研究各种各样的变换?

从信号处理角度来说 分析平稳信号所蕴涵的信息, 一般地Fourier 变换就能应付自如。但以不稳定动力系统为特征的物理世界, 信号往往具有如下特点: 非平稳、非线性、非确定、非可积、非连续、非光滑、非周期、非对称等等。使用Fourier 变换分析、解释非平稳信号, 就显得无能为力…

【日志系列】日志框架Log4j2源码解析

初始化 LoggerFactory private static final Logger logger LoggerFactory.getLogger(LogFilter.class);LoggerFactory#getLogger() public static Logger getLogger(Class<?> clazz) {Logger logger getLogger(clazz.getName());if (DETECT_LOGGER_NAME_MISMATCH) {…

设计模式 Map+函数式接口减少if else

参考资料 代码优雅之道——如何干掉过多的if else 目录 一. 前期准备1.1 标记邮箱种类的接口1.2 邮箱类型区分类1.3 入参Form实体类 二. 邮件发送的业务聚合类三. 定义函数式接口&#xff0c;创建邮件发送的Map四. 效果 一. 前期准备 1.1 标记邮箱种类的接口 import java.la…

一文让你真正了解正则表达式

1 正则表达式是什么 正则表达式(Regular Expression)其实就是一门工具&#xff0c;目的是为了字符串模式匹配&#xff0c;从而实现搜索和替换功能。它起源于上个20世纪50年代科学家在数学领域做的一些研究工作&#xff0c;后来才被引入到计算机领域中。从它的命名我们可以知道…

3自由度并联绘图机器人实现写字功能(二)

1. 功能说明 本文示例将实现R305b样机3自由度并联绘图机器人写字的功能。本实验使用的样机是用探索者兼容零件制作的。 2. 电子硬件 在这个示例中&#xff0c;采用了以下硬件&#xff0c;请大家参考&#xff1a; 主控板 Basra主控板&#xff08;兼容Arduino Uno&#xff09; 扩…

Visual Studio C# WinForm开发入门(5):TabControl 控件使用

TabContrl选项卡控件可创建标签化窗口&#xff0c;在实际 编程中经常用到&#xff0c;该控件的作用是将相关的组件组合到一系列选项卡页面上。 比如下面的例子&#xff0c;在tabPage1页面和tabPage2页面各放了2个checkBox控件&#xff0c;通过点击不同page即可切换&#xff1a;…

交叉编译工具

工具链有一个松散的名称约定&#xff0c;如 arch[-vendor][-os]-abi-language . arch 适用于架构&#xff0c;编译器用于哪个目标平台&#xff1a; arm &#xff0c; mips &#xff0c; x86 &#xff0c; i686 ... vendor 是工具链供应商&#xff0c;以厂家名称命名的&#xf…

权威学者、企业CFO荟聚上海国家会计学院,共探「智能会计 价值财务」

4月21日&#xff0c;由用友主办的「智能会计 价值财务」2023企业数智化财务创新峰会在上海国家会计学院圆满举办。学院权威教授、业内专家与来自央国企、行业领先企业的财务先锋&#xff0c;线下云端共聚一堂&#xff0c;数万人共探大型企业财务数智化的全新价值主张。 会议伊始…

WLAN - 五大安全措施

文章目录 1 概述2 五大安全措施2.1 SSID 访问控制2.2 物理地址过滤 MAC2.3 有线等效保密 WEP2.4 WPA&#xff08;IEEE 802.11i 草案&#xff09;2.5 WPA2&#xff08;IEEE 802.11i&#xff09; 3 扩展3.1 网工软考真题 1 概述 无线局域网面临着两个主要问题&#xff0c;一是增…