数组作为函数参数为什么要多传一个长度——Day10 学习记录从数组传参到日历打印学完函数之后我开始用函数封装各种功能。但很快就遇到了问题——把数组传给函数后用sizeof计算长度结果根本不是数组的大小。后来才知道这是 C 语言最经典的数组退化为指针规则。今天就把数组传参、字符串操作函数、作用域和存储类别串起来讲一遍最后用一个打印日历的例子收尾。① 数组传参的本质为什么不是传整个数组很多新手包括我第一次写数组传参时都会这么想“把整个数组传进去不就行了”但 C 语言偏不。它不传整个数组只传首元素的地址。原因数组可能很大。如果每次传参都复制整个数组性能开销太大了。C 语言的设计哲学是相信程序员不做多余的事。所以数组名做参数时编译器把它解释为指针——准确地说是退化为首元素地址。既然函数拿到的只是一个地址它当然不知道数组有多长。这就是为什么必须额外传一个长度参数。与之对比字符数组字符串不需要传长度因为字符串自带\0结束标志。函数只需一直读到\0就知道到哪结束了。一句总结数组传参退化为指针函数拿不到数组大小所以要么额外传长度要么靠 ‘\0’ 结尾。② 一维数组传参怎么写错误示例voidprintArray(inta[]){intlensizeof(a)/sizeof(a[0]);// 错sizeof(a) 是指针大小}这个坑我踩过不止一次。sizeof(a)在函数里返回的是指针的字节数8 或 4不是数组的大小。正确写法voidprintArray(inta[],intlen){for(inti0;ilen;i)printf(%d ,a[i]);}printArray(a,10);// 调用时传入长度字符数组就不一样了voidprintStr(chars[]){for(inti0;s[i]!\0;i)printf(%c,s[i]);}printStr(hello);// 不需要传长度一句总结整型数组传参要加长度参数字符数组靠 ‘\0’ 结尾。③ 二维数组传参为什么列数不能省略错误示例voidoutputArray(inta[][],introw);// 编译错误为什么错二维数组本质上是数组的数组。访问a[i][j]时编译器需要计算偏移量地址 首地址 (i * 列数 j) * 元素大小列数不指定这个公式就没法算。行数可以省略因为编译器不需要行数就能算出地址。正确写法voidoutputArray(inta[][4],introw){for(inti0;irow;i){for(intj0;j4;j)printf(%d ,a[i][j]);printf(\n);}}二维字符数组同理char str[][10]列数必须写行数可以省略。一句总结二维数组传参必须指定列数因为编译器需要列数来定位元素。④ 字符串操作函数自己动手实现标准库提供了string.h但自己实现一遍能更深刻理解原理。Strlen计算字符串长度遇到\0就停统计\0之前的字符数。intmyStrlen(constchars[]){inti0;while(s[i]!\0)i;returni;}Strcpy复制字符串注意要把\0也复制过去。voidmyStrcpy(chardest[],constcharsrc[]){inti0;while(src[i]!\0){dest[i]src[i];i;}dest[i]\0;// 别忘了复制结束符}Strcat拼接字符串先找到 dest 的末尾\0的位置再从那里开始复制 src。voidmyStrcat(chardest[],constcharsrc[]){inti0,j0;while(dest[i]!\0)i;// 找到 dest 末尾while(src[j]!\0){dest[i]src[j];i;j;}dest[i]\0;}Strcmp比较字符串逐个字符比较 ASCII 码找到第一个不同的字符就返回差值。intmyStrcmp(constchars1[],constchars2[]){inti0;while(s1[i]!\0s2[i]!\0){if(s1[i]!s2[i])returns1[i]-s2[i];i;}returns1[i]-s2[i];}一句总结四个操作函数的本质都是遍历 ‘\0’ 结尾的字符数组。⑤ 作用域与存储类别作用域讲的是在哪能用生命周期讲的是啥时候销毁。局部变量 vs 全局变量intg10;// 全局变量所有函数都能用voidfunc(){inta5;// 局部变量只能在 func 里用}就近原则如果局部和全局同名局部优先。存储类别关键字关键字存储位置生命周期作用域说明auto栈块内块内默认局部变量static全局区程序始终块内只初始化一次register寄存器建议块内块内编译器可忽略extern外部存储程序始终全局声明外部变量static最常用——它让局部变量在函数多次调用之间保持值不变但其他函数又访问不到。一句总结作用域决定可见性static 让局部变量拥有全局生命周期但保持局部访问限制。⑥ 综合实战打印日历今天最后一个实战打印 2026 年 7 月的日历。拆成四个函数每个只做一件事#includestdio.hintisLeapYear(intyear){return(year%40year%100!0)||(year%4000);}intgetMonthDays(intyear,intmonth){intdays[]{31,28,31,30,31,30,31,31,30,31,30,31};if(month2isLeapYear(year))return29;returndays[month-1];}intgetAllDays(intyear,intmonth){inttotal0;for(inty1;yyear;y)totalisLeapYear(y)?366:365;for(intm1;mmonth;m)totalgetMonthDays(year,m);returntotal;}voidprintCal(intyear,intmonth){intdaysgetMonthDays(year,month);intweekday(getAllDays(year,month)1)%7;// 2026.1.1 是周四printf( %d 年 %d 月\n,year,month);printf(日 一 二 三 四 五 六\n);for(inti0;iweekday;i)printf( );for(intd1;ddays;d){printf(%2d ,d);if((weekdayd)%70)printf(\n);}printf(\n);}intmain(){printCal(2026,7);return0;}核心思路从公元 1 年 1 月 1 日到目标年月的 1 日算出总天数总天数 % 7 得到星期几再按格式输出。每日一练运行上面的代码验证 2026 年 7 月的日历是否正确。你可以把年份和月份改成其他值测试。今日避坑指南坑原因怎么避函数内 sizeof(a) 不是数组大小数组名退化为指针额外传 len二维数组列数省略导致编译错误编译器无法计算偏移形参写int a[][N]Strcpy 忘记复制 \0目标数组不是合法字符串循环结束后加dest[i]\0Strcat 目标空间不够拼接后越界确保 dest 容量足够全局变量滥用函数间耦合高、难调试能用传参就别用全局忘记闰年判断2 月天数算错isLeapYear 单独封装今日学习感悟今天最有价值的收获是理解了 C 语言数组传参退化为指针这条规则。以前写sizeof(a)在函数里算出指针大小时我只觉得莫名其妙。今天搞明白了背后的原因——性能优先的设计哲学一切都有道理。另一个收获是日历打印这个实战。把一个看起来复杂的问题拆成四个小函数每个函数独立测试最后组合起来。这个拆分思路在嵌入式开发中特别重要一个函数只做一件事做好一件事。Day10 学习记录明天继续。
企业数字化 ERP 产品动态
相关推荐
Windows 10任务栏空白图标修复全攻略 1. 问题现象与初步排查Windows 10任务栏空白图标问题通常表现为系统托盘区域出现无文字说明、无功能响应的透明或白色方块。这种情况多发生在系统更新后、软件异常退出或资源管理器重启时。根据我多年处理Windows系统问题的经验,这类故障往往与图标缓存损坏、注册表… · 2026/10/29 14:33:07
基于AI的媒体资产管理:从非结构化素材到可检索知识图谱 如果你是一位开发者,或者对内容创作、视频制作、数字资产管理感兴趣,那么“花絮Vlog”这个看似娱乐化的概念,可能比你想象中更值得关注。它背后代表的,是一套关于“非结构化内容资产”的采集、整理、复用与价值挖掘的完整技术栈和… · 2026/11/1 7:45:47
特种作业操作证巴中怎么考?学历不高怕报不上名?含金量到底有多高? 特种作业操作证巴中怎么考?学历不高怕报不上名?含金量到底有多高? 你是不是也这样?手里活儿干得不错,可就是因为学历不高,总觉得自己考不了特种作业操作证,怕被拒绝,怕没用,怕浪费钱?其实不然,特种作业操作证巴中地区的报考门槛,远没有你想象的那… · 2026/11/12 3:38:58
低压电工证几年一复审在哪考最靠谱?别再交冤枉钱了 低压电工证几年一复审在哪考最靠谱?别再交冤枉钱了 怕考不过白交培训费?低压电工证几年一复审, 在哪考 直接决定你能不能顺利拿证,也关系到你以后的就业和薪资。很多电工师傅都遇到过,培训费交了,考试不过,钱打水漂。今天就从一个许昌劳务班组负责人… · 2026/11/12 3:38:58
工地太忙根本没时间复习考试?电工证怎么样的?怎么报名最省心? 工地太忙根本没时间复习考试?电工证怎么样的?怎么报名最省心? 工地太忙根本没时间复习考试,这是大多数一线作业人员的真实写照。特别是像你这样刚毕业、刚进工地的应届生,面对繁重的施工任务,还要抽时间备考电工证,简直是雪上加霜。但你得明白,… · 2026/11/12 3:38:57
工地太忙根本没时间复习考试?隔省办的电工证能用吗值不值得考 工地太忙根本没时间复习考试?隔省办的电工证能用吗值不值得考 工地太忙根本没时间复习考试,你是不是也经常在赶工期、盯现场、处理各种突发状况,根本腾不出时间来准备电工证考试?尤其是很多工人从老家赶来,想着先找份活干着,边干边准备,结果到了现场才… · 2026/11/12 3:37:57
电工证丢失还能补吗?千万别踩坑,丢了证等于失业 电工证丢失还能补吗?千万别踩坑,丢了证等于失业 你正在找工作,但手里的电工证突然丢了,这下怎么办?别急,先别慌, 电工证丢失还能补吗 ?答案是肯定的,但 千万别踩坑 ,补办流程如果不了解,可能会耽误你上岗、甚至影响到你的收入。… · 2026/11/11 12:18:07
电力电缆作业证直播报名入口与办理流程良心建议 电力电缆作业证直播报名入口与办理流程良心建议 你是不是也担心学历不高报不了名?别急,今天就给你讲讲 电力电缆作业证直播 的报名流程和那些你必须知道的干货, 良心建议 在这里,别错过。 电力电缆作业证直播报名需要什么条件?… · 2026/11/11 19:07:25
英德电工证报考费多少钱,怕考不过白交培训费?看完这篇别再踩坑 英德电工证报考费多少钱,怕考不过白交培训费?看完这篇别再踩坑 怕考不过白交培训费?英德电工证报考费多少钱,你真的了解吗?现在市面上培训机构五花八门,价格参差不齐,很多人一不小心就花了冤枉钱,结果还考不过。别急,今天就来给你说清楚英德电工证的… · 2026/11/11 17:14:54
电工证设年审有效期多久官方回应来了,工地太忙根本没时间复习考试 电工证设年审有效期多久官方回应来了,工地太忙根本没时间复习考试 工地太忙根本没时间复习考试,这是很多一线电工、焊工、高处作业人员的真实写照。尤其是像你这样刚毕业的鹤壁工程类毕业生,一边要找工作,一边要考证,时间紧张,复习效率低。但你可能不知… · 2026/11/12 0:00:56
新乡电工证实操怕挂科?电工作业动漫图+报考避坑全解析 新乡电工证实操怕挂科?电工作业动漫图+报考避坑全解析 实操考试心里没底怕挂科?你不是一个人。新乡的水利工程从业者,很多在报考电工证的时候都担心自己操作不熟练、考试不通过, 千万别踩坑 ,选对资料和方法真的能提高通过率。… · 2026/11/12 0:00:56
网电工证千万别踩坑:实操考试心里没底怕挂科怎么破? 网电工证千万别踩坑:实操考试心里没底怕挂科怎么破? 实操考试心里没底怕挂科,这是很多准备报考【网电工证】的学员最真实的感受。尤其是在高压电工、低压电工等工种上,操作环节的容错率极低,一旦失误就可能直接被判定不合格。很多人因为担心挂科而放弃考… · 2026/11/12 0:00:56
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/10 20:19:29
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/10 19:22:45
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/11 17:15:20