指针(3):strlen的模拟实现和传址调用 指针3strlen的模拟实现和传址调用1.strlen的模拟实现1.1 streln的介绍1.2 strlen的模拟实现1.3 注意1.4 补充2.传址调用1.strlen的模拟实现1.1 streln的介绍库函数strlen的功能是求字符串的长度统计的是字符串中\0之前的字符的个数函数原型如下size_tstrlen(constchar*str);参数str接收⼀个字符串的起始地址然后开始统计字符串中 \0 之前的字符个数最终返回⻓度。strlen的运用#includestdio.h#includestring.hintmain(){intretstrlen(abcdef);printf(%d,ret);return0;}字符串“abcdef”在内存中实际存储的是a b c d e f \0共7个字节strlen只统计\0之前字符的数量因此输出结果为6。1.2 strlen的模拟实现根据上面对strlen函数原型的分析我们可以得知如果要模拟实现只要从起始地址开始向后逐个字符的遍历只要不是 \0 字符计数器就1这样直到 \0 就停⽌。接下来就让我们来完成strlen模拟实现的代码#includestdio.hsize_tmy_strlen(constchar*str){size_tcount0;while(*str){str;count;}returncount;}intmain(){size_tretmy_strlen(abcdef);printf(%zu\n,ret);return0;}首先将 “abcdef” 传到函数my_strlen中设置一个计数器count用来统计该字符串\0之前的字符的个数通过while循环遍历该字符串\0之前的字符每循环一次指针向后移动一位并且使得计数器count加一遍历完成后返回count函数模拟完成1.3 注意通过观察我们可以发现模拟函数实现时我们定义的用来接收my_strlen的ret的类型为size_t无符号整数类型而上面我们在运用strlen时用来接收其返回值时用的ret的类型为int但最后输出结果都正确这是为什么呢。这是因为字符串“abcdef”中字符数量太小用int来接收也足够当字符数量够大时用int接收就会出现错误所以最好是使用size_t 和 %zu来接收和打印当然在字符串比较小的时候也可以用int 和 %d来接收和打印。此外还有一个需要注意的点由于strlen的返回值是无符号整数因此两个strlen相减是不能得到负数的看下面这个例子if(strlen(hi)-strlen(hello)0)在这个例子中看似strlen(“hi”)得到数是2strlen(“hello”)得到的数是42 - 4 0,但是strlen返回值是size_t不存在负数只用正数因此strlen(“hi”) - strlen(“hello”所得到的值是一个很大的无符号正数因此这个式子永远大于0.1.4 补充根据之前章节里面所提到的指针-指针我们可以用另一种方式来实现strlen的模拟实现即首先记录指针的起始位置然后遍历字符串得到指针结束时的位置用结束指针-起始指针即可得到字符的数量。#includestdio.hsize_tmy_strlen(constchar*str){constchar*startstr;while(*str){str;}returnstr-start;}intmain(){size_tretmy_strlen(abcdef);printf(%zu\n,ret);return0;}注意指针相减得到的数字是有符号整数类型但return时会将其隐式转化size_t类型因此无需进行强制类型转化。2.传址调用我们学习指针是为了解决问题那么有哪些问题是只有指针才能解决的呢我们来看这样一个问题写一个函数交换两个整型变量的值。经过一番思考我们可能会写出这样的代码#includestdio.hvoidswap(intx,inty){intc0;cx;xy;yc;}intmain(){inta5;intb3;swap(a,b);printf(%d %d,a,b);return0;}让我们运行起来看看是否能够达到目的我们发现这并没有产生交换的后果这是为什么呢让我们来通过调试观察一下。我们发现在main函数内部创建了变量a b他们的地址分别为0x000000026dc6ff6c4 和 0x000000026dc6ff6e4而在调用swap函数时我们将 a 和 b 传递给swap函数swap函数在函数内部创建了形参x 和 y用来接收a 和 b的值但是x的地址是0x000000026dc6ff6a0y的地址是0x000000026dc6ff6a8x和y确实接收到了a和b的值不过x的地址和a的地址不⼀样y的地址和b的地址不⼀样相当于x和y是独⽴的空间而我们又知道数据都是存储在地址所对应的内存单元当中他们的地址不同因此他们所对应的内存单元也就不同那么在swap函数内部交换x和y的值⾃然不会影响a和b当swap函数调⽤结束后回到main函数a和b的值没法交换。这就是传值调⽤因此我们可以得出结论实参传递给形参的时候形参会单独创建⼀份临时空间来接收实参对形参的修改不影响实参。因此swap失败了那我们该怎么办呢其实只需要将a和b的地址传递给swap函数让swap函数通过地址间接的操作a和b的值这样就能够达到交换a和b的值的功能了。#includestdio.hvoidswap(int*x,int*y){intc0;c*x;*x*y;*yc;}intmain(){inta5;intb3;swap(a,b);printf(%d %d,a,b);return0;}由此我们看到代码成功的完成了任务这⾥调⽤swap函数的时候是将变量的地址传递给了函数这种函数调⽤⽅式叫传址调⽤传址调⽤可以让函数和主调函数之间建⽴真正的联系在函数内部可以修改主调函数中的变量所以未来函数中只是需要主调函数中的变量值来实现计算就可以采⽤传值调⽤。如果函数内部要修改主调函数中的变量的值就需要传址调⽤。

相关新闻

最新新闻

0061基于 SpringBoot 的投稿与稿件处理系统设计与实现

0061基于 SpringBoot 的投稿与稿件处理系统设计与实现

基于 SpringBoot 的投稿与稿件处理系统设计与实现 本文分享一套基于 SpringBoot Vue 前后端分离架构开发的投稿与稿件处理系统,完整覆盖用户注册、稿件投递、分类管理、专家审稿、消息通知等核心业务流程,可作为毕业设计项目、小型期刊 / 社团投稿平台的…

2026/8/14 23:21:57
做PPT选工具之前,先搞清楚你卡在哪一步

做PPT选工具之前,先搞清楚你卡在哪一步

很多人搜索"PPT制作软件推荐"时,真正想解决的问题其实不一样:有人卡在内容组织,有人卡在视觉排版,有人卡在从资料到成稿的转化效率,还有人卡在团队协作和反复修改。不同环节的最优工具差异很大,盲…

2026/8/14 23:21:57
青岛选瓷砖服务商

青岛选瓷砖服务商

行业痛点分析当前青岛瓷砖选购领域的核心技术挑战集中在三个维度:一是正品溯源体系缺失,普通消费者缺乏专业检测能力,无法区分贴牌砖与广东原厂砖的性能差异;二是库存调度能力不足,中小服务商普遍无规模化现货储备&…

2026/8/14 23:21:57
中网B2B战略咨询:真正全案=战略+全链路+长期陪跑

中网B2B战略咨询:真正全案=战略+全链路+长期陪跑

中网B2B战略咨询致力于为企业提供全面的战略规划服务、提到“真正全案”的理念。这除了涉及精确的市场战略、还涵盖了全链路的执行能力和长期等陪跑支持。通过整合商业模式设计与可持续增长计划,中网帮助企业在竞争激烈的市场中实现卓越表现。全案战略确保了从市场分…

2026/8/14 23:21:57
工业大模型入门指南:小白程序员必备,收藏学习进阶秘籍!

工业大模型入门指南:小白程序员必备,收藏学习进阶秘籍!

制造业面临数据复杂、约束多等挑战,传统模型难以应对。本文介绍工业大模型如何解决这些问题,通过分层架构实现“感知-理解-规划-执行-评估-优化”闭环决策。文章涵盖数据与数字线程、模型、知识与机理、智能体与工具、治理与运营等层面,并给出…

2026/8/14 23:21:57
AI Coding行业最新动态与学习参考(2026年8月第2周)

AI Coding行业最新动态与学习参考(2026年8月第2周)

一、AI Coding 实用建议与趋势动态(5条)AI编程从"副驾驶"转向"默认自主代理":Claude Code将于8月14日起对Pro/Max/Team用户默认开启Auto模式,通过安全分类器自动判断操作风险(拦截89%危险命令&…

2026/8/14 23:16:57