数组作为函数参数为什么要多传一个长度_Day10
数组作为函数参数为什么要多传一个长度——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 学习记录明天继续。

相关新闻

windows网络适配器驱动开发-开发 WiFiCx 客户端驱动程序(八)

windows网络适配器驱动开发-开发 WiFiCx 客户端驱动程序(八)

电源策略更改对于电源管理,客户端驱动程序使用 NETPOWERSETTINGS 对象 ,例如其他类型的 NetAdapterCx 客户端驱动程序。为了在系统处于工作状态(S0)状态时支持设备闲置,驱动程序调用 WdfDeviceAssignS0IdleSettings 并…

2026/11/13 15:29:00 阅读更多 →
Windows文件关联机制与注册表操作详解

Windows文件关联机制与注册表操作详解

1. 文件关联的本质与系统机制在Windows操作系统中,文件关联(File Association)是一套将特定扩展名的文件与对应应用程序绑定的机制。这个看似简单的功能背后,其实涉及注册表、MIME类型、默认程序设置等多层系统架构。当我们双击一…

2026/11/10 16:08:05 阅读更多 →
国内首个 uv 全链路镜像上线:安装、Python 下载、包索引一站加速

国内首个 uv 全链路镜像上线:安装、Python 下载、包索引一站加速

uv 是 Astral 团队用 Rust 编写的超快 Python 包管理器,比 pip 快 10–100 倍,以一个工具替代 pip、pip-tools、pipx、poetry、pyenv、virtualenv 等一整套工具链。然而在国内,uv 的三大网络环节——安装包下载、Python 解释器安装、Astral 元…

2026/11/7 15:31:06 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/11/13 5:13:25 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/11/13 5:13:25 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/11/13 5:13:25 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/11/12 18:22:26 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/11/12 18:22:25 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/11/13 5:13:25 阅读更多 →

日新闻

周新闻

月新闻