C语言指针核心应用:传址调用——让函数真正「动手」
适用对象学过函数、指针基础理解地址概念的同学本章目标彻底搞懂「传值调用」为什么换不了两个变量「传址调用」为什么可以引入换房间的故事先来玩一个思维实验。场景你现在在 23 楼 A 房间你朋友在 25 楼 B 房间。你想让你们俩换房间住。传值调用错误方式你给酒店前台打电话说「把我房间里的东西和 25 楼 B 换一下」。前台派了两个新服务员去你的房间和朋友的房间把两边的家具互换了一下然后走了。但你呢你还是待在原来的 23 楼 A 房间你人没动动的只是房间里临时出现又消失的两套家具。传址调用正确方式你给前台打电话说「把我的房间和朋友的房间对调前台把我们的房卡换一下」。前台收了你的房卡和朋友的手续把两张房卡上的楼层号对调——你现在真的住进了 25 楼。这个故事就是传值调用和传址调用的本质区别。第一部分传值调用——换了个寂寞1.1 交换两个变量的值失败版#includestdio.h// 传值调用版本x 和 y 是 a、b 的副本voidswap_wrong(intx,inty){inttmpx;xy;ytmp;}intmain(){inta10;intb20;printf(交换前a %d, b %d\n,a,b);swap_wrong(a,b);// 调用后a 和 b 变了吗printf(交换后a %d, b %d\n,a,b);return0;}输出交换前a 10, b 20 交换后a 10, b 20 // 没有任何变化1.2 为什么会失败在swap_wrong(a, b)被调用的一瞬间发生了以下事情创建两个新房间x和y分别从a和b那里拷贝了值——x 10y 20swap_wrong函数在x和y这两个新房间里倒腾把值换了过来函数结束x和y这两个临时房间被系统回收原来的a和b房间纹丝不动——因为它们根本没有参与交换内存快照调用瞬间传值调用前 a 的房间: [10] b 的房间: [20] 调用瞬间创建副本 x 的房间: [10] ← a 的副本 y 的房间: [20] ← b 的副本 a 的房间: [10] ← 原版丝毫未动 b 的房间: [20] ← 原版丝毫未动 函数返回x、y 被回收 a: [10] ← 还是原来那个 a b: [20] ← 还是原来那个 b⚠️提醒传值调用的核心问题是副本隔离——形参是实参的复制品对副本做任何操作都不影响原版。在 C 语言里所有基本类型int、char、float 等默认都是传值调用。第二部分传址调用——让函数直接操作原房间2.1 交换两个变量的值成功版#includestdio.h// 传址调用版本px 和 py 存的是 a 和 b 的地址voidswap_right(int*px,int*py){inttmp*px;// tmp px 便签指向的房间里的值 10*px*py;// px 便签指向的房间里的值 20*pytmp;// py 便签指向的房间里的值 10}intmain(){inta10;intb20;printf(交换前a %d, b %d\n,a,b);swap_right(a,b);// 传入 a 和 b 的地址printf(交换后a %d, b %d\n,a,b);return0;}输出交换前a 10, b 20 交换后a 20, b 10 // 成功2.2 为什么会成功在swap_right(a, b)被调用的一瞬间aa 的地址被拷贝给px——px这张便签上写着「a 在哪间房」bb 的地址被拷贝给py——py这张便签上写着「b 在哪间房」*px *py拿着px的便签找到 a 的房间把里面的值改成 b 的值——a 20*py tmp拿着py的便签找到 b 的房间把里面的值改成 a 的值——b 10函数结束两个便签px、py被回收但a和b的房间里的值已经被改掉了内存快照调用过程传址调用瞬间 a 的房间: [10] ←──────────────┐ b 的房间: [20] ←──────────────┐│ px ──────→ [10] a 的副本便签指向 py ──────→ [20] b 的副本便签指向 *px *py 执行后 a 的房间: [20] ← py 便签改了这里 b 的房间: [20] ← 临时 tmp 20 *py tmp 执行后 a 的房间: [20] b 的房间: [10] ← tmp 10写进了 b 的房间2.3 传值 vs 传址——对比总结对比维度传值调用传址调用传入函数的变量的副本值拷贝变量的地址形参是什么普通变量int x指针变量int *px能修改实参吗❌ 不能✅ 能对内存的影响只在函数内部有效直接修改原房间传入的是什么楼层号无楼层号副本不是房间真正的楼层号地址一句话总结传值调用把房间里的东西值抄了一份给函数传址调用把楼层号地址告诉函数让函数自己找过去。第三部分传址调用的典型应用场景3.1 在函数内部修改多个返回值函数只能有一个返回值return只能写一个但如果需要函数一次返回多个结果呢用传址调用#includestdio.h// 一次返回两个计算结果求和 求积voidcalc(inta,intb,int*p_sum,int*p_product){*p_sumab;// 把和写入 p_sum 指向的房间*p_producta*b;// 把积写入 p_product 指向的房间}intmain(){intx3,y5;intsum0,product0;calc(x,y,sum,product);printf(和 %d, 积 %d\n,sum,product);// 和 8, 积 15return0;}技巧如果你发现一个函数需要「返回」两个以上的值首先想到传址调用——让调用者提供「房间」函数负责「写入」。3.2 判断两个数的大小并返回最大值#includestdio.h// 返回两个数中较大的同时把较小的存到 min 指向的位置intmax_min(inta,intb,int*p_min){*p_min(ab)?a:b;// 把较小的值写入 p_min 指向的房间return(ab)?a:b;// 较大的值通过 return 返回}intmain(){inta8,b13;intmin_val;intmax_valmax_min(a,b,min_val);printf(最大值 %d, 最小值 %d\n,max_val,min_val);// 输出最大值 13, 最小值 8return0;}3.3 让函数内部访问大型数据结构避免拷贝如果你有一个超大的数组直接传值调用会把整个数组拷贝一份效率极低。传地址只传 8 字节64位系统效率高得多#includestdio.hvoidprint_big_array(int*arr,intlen)// 传地址只拷贝 8 字节{for(inti0;ilen;i)printf(%d ,arr[i]);}intmain(){intbig[1000000];// 400 万字节的数组// ... 初始化 big 数组print_big_array(big,1000000);// ✅ 只传地址不拷贝整片内存return0;}⚠️提醒传地址比传值在大数据量场景下有压倒性的性能优势。另外如果函数的参数是数组永远传地址——因为数组名本身就是首元素地址传给形参时会发生退化详情见数组与指针章节。第四部分手写 strlen——传址的实际应用4.1 strlen 是什么strlen()是 C 语言标准库函数专门求字符串的长度——从字符串开头数起遇到第一个\0字符串结束标志之前一共有多少个字符。#includestring.hintmain(){intlenstrlen(hello);printf(%d,len);// 输出5return0;}4.2 手写 strlen 的思路核心思路从字符串起始地址出发一个字符一个字符往后数数到\0就停。怎么判断「是不是\0」用while (*str ! \0)。#includestdio.h#includeassert.h// my_strlen求字符串长度intmy_strlen(constchar*str)// const防止函数内部意外修改字符串{assert(str!NULL);// 安检门str 绝不能是 NULLintcount0;while(*str!\0){// 当前字符不是结束标志就继续数count;str;// 指针往后挪一个字符}returncount;}intmain(){printf(%d\n,my_strlen(hello));// 5printf(%d\n,my_strlen());// 0空字符串printf(%d\n,my_strlen(hi\0world));// 2遇到 \0 就停了return0;}4.3 strlen 手写版的两个关键点关键点一const 保护参数intmy_strlen(constchar*str)加了const之后如果函数里不小心写了*str X编译器会报错——防止你把调用者传进来的字符串给改了。关键点二assert 守卫入口assert(str!NULL);如果调用者手滑写了my_strlen(NULL)没有 assert 的话程序会直接崩溃——而且崩溃位置可能在 strlen 内部的任意一行。有了 assert崩溃位置精确在第几行一眼定位问题。⚠️提醒assert()只在调试版本Debug里生效。在发布版本Release里assert会被编译器直接删除不影响性能。所以 assert 是专门给开发者用的工具不是给最终用户的保护机制。第五部分经典面试题精讲面试题一传值和传址的根本区别是什么标准答案传值调用把实参的值拷贝一份给形参形参是独立的新变量。对形参的修改不影响实参。传址调用把实参的地址拷贝一份给形参指针通过这个地址直接访问原变量。对形参指向内容的修改直接影响原变量。面试加分回答传值调用的本质是副本隔离——就像你复印了一份文件给别人别人在复印件上画再多东西原件纹丝不动。传址调用的本质是共享坐标——你把房间的楼层号告诉了别人别人可以直接进那个房间改东西改完你回来发现房间确实变了。面试题二下面的代码输出什么#includestdio.hvoidf(int*p,int*q){pq;// p 指向了 q 指向的房间*p*q2;// p 指向的房间的值 q 指向的值 2}intmain(){inta1,b2;f(a,b);printf(%d %d,a,b);// 输出什么return0;}逐步推演初始a 1, b 2 f(a, b) 被调用 px a, py b px 指向 apy 指向 b p q px py px 现在也指向 b 了px 和 py 指向同一个房间 b *p *q 2 *px *py 2 即b 的房间 b 的值 2 2 2 4 函数返回 a 1 a 从未被修改 b 4 b 被修改了 输出1 4答案1 4⚠️提醒这里p q只改变了指针变量p本身它存的地址并没有改变a的值。但*p *q 2通过q的地址直接修改了b所以b变了。面试官经常在这个地方设坑问「p q会不会影响a」——不会因为只改了p这个便签的指向没有改a所在的房间。面试题三下面这个函数能交换两个数吗为什么voidswap(int*px,int*py){int*tmppx;pxpy;pytmp;}答案不能这个函数的意图是把px和py这两张便签对调——但问题是px、py、tmp都是局部变量函数参数。p q只是让局部变量px指向了另一个地址对调用者毫无影响。真正能交换的版本用的是int tmp普通变量而不是int *tmp指针voidswap(int*px,int*py){inttmp*px;// ✅ 用普通变量 tmp 存值*px*py;*pytmp;}本章总结传值调用 vs 传址调用传值调用传址调用形参类型int xint *px实参传入值的拷贝地址的拷贝能修改实参吗❌✅性能大数据量差整块拷贝好只传 8 字节什么时候必须用传址函数需要修改多个外部变量函数参数是大数组 / 大结构体需要返回一个以上的值手写 strlen 的三步① assert(str ! NULL) → 防守检查 NULL ② while (*str ! \0) → 循环不是 \0 就继续 ③ count / str → 计数数一个指针挪一个

相关新闻

珍珠棉设备和普通发泡机的区别,关键在这里

珍珠棉设备和普通发泡机的区别,关键在这里

为什么你的珍珠棉总是回弹性差、易碎裂? 你是不是也遇到过这种情况:采购的珍珠棉(EPE)片材看起来厚实,但一压就塌、回弹慢,甚至运输途中就碎成渣?很多厂家以为是原料问题,其实根源往…

2026/8/6 7:05:10 阅读更多 →
磁力计技术全解析:从霍尔效应到量子传感,原理、选型与应用实战

磁力计技术全解析:从霍尔效应到量子传感,原理、选型与应用实战

1. 磁力计的世界:从指南针到量子传感磁力计,这个听起来有些专业的词汇,其实离我们的生活并不遥远。从我们手机里的电子罗盘,到地质勘探中寻找矿藏,再到医学影像技术里的核心部件,磁力计都在默默地发挥着作用…

2026/8/6 7:05:10 阅读更多 →
深度优先搜索(DFS)算法详解:从原理到实战应用

深度优先搜索(DFS)算法详解:从原理到实战应用

1. 从一笔画问题到算法核心:为什么我们需要深度优先搜索?最近在社区里看到一个挺有意思的题目:一个7*5的格子,如何遍历所有格子,一笔联通第二行左1格和第四行右1格?这本质上就是一个路径搜索问题。很多朋友…

2026/8/6 7:05:10 阅读更多 →

最新新闻

2024 Excel函数公式实战指南:从核心函数到动态数组,告别重复劳动

2024 Excel函数公式实战指南:从核心函数到动态数组,告别重复劳动

1. 项目概述:为什么你需要一份2024年的Excel函数与公式指南?如果你还在用“复制粘贴”和“手动计算”来对付Excel里那些密密麻麻的数据,那这份指南就是为你准备的。我干了十多年数据分析,见过太多同事和学员,面对一个简…

2026/8/6 7:55:40 阅读更多 →
扣子事件触发器安全加固手册:防止恶意payload注入、重放攻击与越权触发(含OWASP合规检查清单)

扣子事件触发器安全加固手册:防止恶意payload注入、重放攻击与越权触发(含OWASP合规检查清单)

更多请点击: https://intelliparadigm.com 第一章:扣子事件触发器安全加固手册:防止恶意payload注入、重放攻击与越权触发(含OWASP合规检查清单) 扣子(Coze)平台的事件触发器(Event…

2026/8/6 7:55:40 阅读更多 →
2026年GEO优化深度解读:郑州企业如何抓住AI搜索新流量?

2026年GEO优化深度解读:郑州企业如何抓住AI搜索新流量?

2026年GEO优化深度解读:郑州企业如何抓住AI搜索新流量?导读:当用户不再打开搜索引擎,而是直接问AI"郑州哪家工厂做盾构机配件靠谱",你的企业还能被找到吗?这就是GEO(生成式引擎优化&a…

2026/8/6 7:55:40 阅读更多 →
小程序定制开发公司怎么选?源码、买断、页面设计和长期维护对比

小程序定制开发公司怎么选?源码、买断、页面设计和长期维护对比

小程序定制开发公司怎么选?源码、买断、页面设计和长期维护对比小程序定制开发公司怎么选,已经不能只问“能不能按需求做”。企业更需要确认的是源码、买断、页面设计、后台功能、接口、验收和长期维护之间的边界。很多项目预算失控,是因为把…

2026/8/6 7:55:40 阅读更多 →
基于规则匹配与模板填充的智能回复生成器实战指南

基于规则匹配与模板填充的智能回复生成器实战指南

最近在开发中遇到一个很有意思的需求:需要根据用户输入的文本,自动生成一个既酷炫又带点调侃意味的“金句”作为回应。比如用户说“今天好累”,系统能回一句“man!what can i say”。这种需求在社交应用、智能客服或者游戏对话系统…

2026/8/6 7:55:40 阅读更多 →
揭秘建设网站用的软件:从小白到专家的完整攻略与避坑指南

揭秘建设网站用的软件:从小白到专家的完整攻略与避坑指南

说实话,以前我觉得搞网站那是程序员的事,跟我这种普通小老板或者自媒体人有什么关系?那时候我觉得网站这东西,要么花钱找外面公司做,要么自己啃那些像天书一样的代码,想想都头大。但是,随着这两年互联网环境的变迁,尤其是现在大家越来越重视个人IP,越来越重视私域流量…

2026/8/6 7:54:39 阅读更多 →

日新闻

深入解析LimboAI C++内核:架构设计与性能优化实战

深入解析LimboAI C++内核:架构设计与性能优化实战

1. 项目概述:为什么我们需要深入LimboAI的C内核?如果你是一名使用Godot引擎的游戏开发者,尤其是对AI行为逻辑有较高要求的项目,那么LimboAI这个名字你大概率不会陌生。它作为Godot 4生态中一个备受瞩目的行为树与状态机插件&#…

2026/8/6 0:00:06 阅读更多 →
Unity 2D游戏敌人AI系统:基于PlayMaker状态机与2D Toolkit的实战开发

Unity 2D游戏敌人AI系统:基于PlayMaker状态机与2D Toolkit的实战开发

1. 项目概述与核心思路大家好,我是老张,一个在游戏开发一线摸爬滚打了十多年的老码农。今天咱们接着聊《空洞骑士》风格2D动作游戏的Demo制作。上一期我们搭好了基础框架,处理了角色移动和碰撞,这一期,我们要让游戏世界…

2026/8/6 0:00:06 阅读更多 →
被动防火门市场前景发展趋势

被动防火门市场前景发展趋势

被动防火门依靠材质结构、密闭构造阻隔烟火蔓延,无需电控启动,是建筑被动消防系统核心构件,行业依托新规管控、城市更新、工业安全升级迎来稳定扩容,整体朝着合规化、专项化、低碳化、智能化方向发展。现阶段 GB12955‑2024 新版国…

2026/8/6 0:00:06 阅读更多 →

周新闻

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

1. 从水管网络到最大流:一个核心问题的诞生想象一下,你是一个城市供水系统的总工程师。你的城市有多个水源(水库),需要通过一个复杂的地下管道网络,将水输送到各个居民区。每条管道都有其最大通水能力&…

2026/8/5 15:00:43 阅读更多 →
基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台…

2026/8/5 13:13:56 阅读更多 →
MATLAB xcorr函数详解:从互相关原理到四大实战应用

MATLAB xcorr函数详解:从互相关原理到四大实战应用

1. 从一次信号“找茬”说起:为什么我们需要互相关几年前,我在处理一组声学传感器数据时遇到了一个棘手的问题。我有两个麦克风记录了一段相同的音频信号,理论上它们接收到的声音波形应该非常相似,只是由于麦克风位置不同&#xff…

2026/8/5 10:20:36 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/5 23:28:39 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/5 21:00:14 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/5 23:46:51 阅读更多 →